This log will detail notable changes to MyBatis Dynamic SQL. Full details are available on the GitHub milestone pages.
This is a minor release with a few small enhancements. Most deprecated methods will be removed in the next release.
GitHub milestone: https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.3.1+
- Added the ability to specify a JavaType associated with a column. The JavaType will be rendered properly for MyBatis (#386)
- Added a few missing groupBy and orderBy methods on the
select
statement (#409) - Added a check for when a table alias is re-used in error (typically in a self-join) (#425)
- Added a new extension of SqlTable that supports setting a table alias directly within the table definition (#426)
GitHub milestone: https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.3.0+
The major themes of this release include the following:
- Add support for subqueries in select statements - both in a from clause and a join clause.
- Add support for the "exists" and "not exists" operator. This will work in "where" clauses anywhere they are supported.
- Refactor and improve the built-in conditions for consistency (see below). There is one breaking change also detailed below.
- Continue to refine the Kotlin DSL. Many changes to the Kotlin DSL are internal and should be source code compatible with existing code. There is one breaking change detailed below.
- Remove deprecated code from prior releases.
All built-in conditions have been refactored. The changes should have little impact for the vast majority of users. However, there are some changes in behavior and one breaking change.
-
Internally, the conditions no longer hold value Suppliers, they now hold the values themselves. The SqlBuilder methods that accept Suppliers will call the
Supplier.get()
method when the condition is constructed. This should have no impact unless you were somehow relying on the delay in obtaining a value until the condition was rendered. -
The existing "then" and "when" methods have been deprecated and replaced with "map" and "filter" respectively. The new method names are more familiar and more representative of what these methods actually do. In effect these methods mimic the function of the "map" and "filter" methods on "java.util.Optional" and they are used for a similar purpose.
-
The new "filter" method works a bit differently than the "when" method it replaces. The old "when" method could not be chained - if it was called multiple times, only the last call would take effect. The new "filter" methods works as it should and every call will take effect. This allows you to construct map/filter pipelines as you would expect.
-
The new "map" method will allow you to change the datatype of a condition as is normal for a "map" method. You can use this method to apply a type conversion directly within condition.
-
All the "WhenPresent" conditions have been removed as separate classes. The methods that produced these conditions in the SqlBuilder remain, and they will now produce a condition with a "NotNull" filter applied. So at the API level things will function exactly as before, but the intermediate classes will be different.
-
One breaking change is that the builder for List value conditions has been removed without replacement. If you were using this builder to supply a "value stream transformer", then the replacement is to build a new List value condition and then call the "map" and "filter" methods as needed. For example, prior code looked like this
public static IsIn<String> isIn(String...values) { return new IsIn.Builder<String>() .withValues(Arrays.asList(values)) .withValueStreamTransformer(s -> s.filter(Objects::nonNull) .map(String::trim) .filter(st -> !st.isEmpty())) .build(); }
New code should look like this:
public static IsIn<String> isIn(String...values) { return SqlBuilder.isIn(values) .filter(Objects::nonNull) .map(String::trim) .filter(st -> !st.isEmpty()); }
We think this is a marked improvement!
The Kotlin DSL continues to evolve. With this release we have fully built out the DSL, and it is no longer necessary
to use any functions in org.mybatis.dynamic.sql.SqlBuilder
. The advantages of this are many and are detailed on the
Kotlin overview page in the documentation. Many functions in SqlBuilder
have been replaced by
top level functions the org.mybatis.dynamic.sql.util.kotlin.elements
package. In most cases you can switch to the
native Kotlin DSL by simply changing the import statements. For example, you can switch usage of the isEqualTo
function by changing
import org.mybatis.dynamic.sql.SqlBuilder.isEqualTo
to
import org.mybatis.dynamic.sql.util.kotlin.elements.isEqualTo
Several functions that accepted supplier arguments are not present in the Kotlin DSL. This is to avoid difficult and confusing method overload problems for methods that did not offer any real benefit. If you were using one of these methods in the Java DSL, then in the Kotlin DSL you will have to change the function argument from a supplier to the actual value itself.
A breaking change is that Kotlin support for select
and count
statements has been refactored. This will not impact code
created by MyBatis generator. It will have an impact on Spring/Kotlin users as well as MyBatis users that coded joins or
other queries directly in Kotlin. The difference is that the from
clause has been moved inside the lambda for select
and count statements.
Previously, code looked like this:
val selectStatement = select(foo).from(bar) {
where(id, isLessThan(3))
}
The new code looks like this:
val selectStatement = select(foo) {
from(bar)
where(id, isLessThan(3))
}
This change makes the Kotlin DSL more consistent and also makes it easier to implement subquery support in the Kotlin DSL.
- Added a new sort specification that is useful in selects with joins (#269)
- Added the capability to generate a camel cased alias for a column (#272)
- Added subquery support for "from" clauses in a select statement (#282)
- Added Kotlin DSL updates to support sub-queries in select statements, where clauses, and insert statements (#282)
- Added subquery support for "join" clauses in a select statement (#293)
- Added support for the "exists" and "not exists" operator in where clauses (#296)
- Refactored the built-in conditions (#331) (#336)
- Added composition functions for WhereApplier (#335)
- Added a mapping for general insert and update statements that will render null values as "null" in the SQL (#343)
- Allow the "in when present" conditions to accept a null Collection as a parameter (#346)
- Add Better Support for MyBatis Multi-Row Inserts that Return Generated Keys (#349)
- Major improvement to the Kotlin DSL (#353)
- Remove use of "record" as an identifier (it is restricted in JDK16) (#357)
GitHub milestone: https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.2.1+
- Fixed a bug where the In conditions could render incorrectly in certain circumstances. (#239)
- Added a callback capability to the "In" conditions that will be called before rendering when the conditions are empty. Also, removed the option that forced the library to render invalid SQL in that case. (#241)
- Added a utility mapper for MyBatis that allows you to run any select query without having to predefine a result mapping. (#255)
- Added utility mappers for MyBatis that allow you to run generic CRUD operations. (#263)
GitHub milestone: https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.2.0+
This release includes major improvements to the Spring support in the library. Spring support is now functionally equivalent to MyBatis support.
This release includes a significant refactoring of the classes in the "org.mybatis.dynamic.sql.select.function" package. The new classes are more consistent and flexible and should be compatible with existing code at the source level (meaning code should be recompiled for the new version of the library). If you have written your own set of functions to extend the library, you will notice that the base classes 'AbstractFunction" and "AbstractMultipleColumnArithmeticFunction" are now deprecated. Their replacement classes are "AbstractUniTypeFunction" and "OperatorFunction" respectively.
With this release, we deprecated several insert methods because they were inconsistently named or awkward. All deprecated methods have documented direct replacements.
All deprecated code will be removed in the next minor release.
- Added a general insert statement that does not require a separate record class to hold values for the insert. (#201)
- Added the capability to specify a rendering strategy on a column to override the default rendering strategy for a statement. This will allow certain edge cases where a parameter marker needs to be formatted uniquely (for example, "::jsonb" needs to be added to parameter markers for JSON fields in PostgreSQL) (#200)
- Added the ability to write a function that will change the column data type (#197)
- Added the
applyOperator
function to make it easy to use non-standard database operators in expressions (#220) - Added convenience methods for count(column) and count(distinct column) (#221)
- Added support for union queries in Kotlin (#187)
- Added the ability to write "in" conditions that will render even if empty (#228)
- Many enhancements for Spring including:
- Fixed a bug where multi-row insert statements did not render properly for Spring (#224)
- Added support for a parameter type converter for use cases where the Java type of a column does not match the database column type (#131)
- Added a utility class which simplifies the use of the named parameter JDBC template for Java code -
org.mybatis.dynamic.sql.util.spring.NamedParameterJdbcTemplateExtensions
- Added support for general inserts, multi-row inserts, batch inserts in the Kotlin DSL for Spring (#225)
- Added support for generated keys in the Kotlin DSL for Spring (#226)
GitHub milestone: https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.4+
- Added support for reusing WHERE clauses among count, delete, select, and update statements (#152)
- Improved Kotlin support. Previously, several overloaded methods could collide causing queries to be fragile and very dependent on having the correct imports in a Kotlin file. With this improved support there is no longer any ambiguity. (#154)
- Fixed issue where limit and offset in sub-queries could cause a parameter name collision (#142)
GitHub milestone: https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.3+
- Added support for
count(distinct ...)
(#112) - Added support for multiple row inserts (#116)
- Utility classes and a new canonical pattern for MyBatis Generator (CRUD) mappers (#118) (#125) (#128)
- Kotlin Extensions and Kotlin DSL (#133) (#139)
GitHub milestone: https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.2+
- Changed the public SQLBuilder API to accept Collection instead of List for in conditions and batch record inserts. This should have no impact on existing code, but allow for some future flexibility (#88)
- Added the ability to have table catalog and/or schema calculated at runtime. This is useful for situations where there are different database schemas for different environments, or in some sharding situations (#92)
- Add support for paging queries with "offset" and "fetch first" - this seems to be standard on most databases (#96)
- Added the ability to call a builder method on any intermediate object in a select statement and receive a fully rendered statement. This makes it easier to build very dynamic queries (#106)
- Add the ability to modify values on any condition before they are placed in the parameter map (#105)
- Add the ability to call
where()
with no parameters. This aids in constructing very dynamic queries (#107)
GitHub milestone: https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.1+
- Limit and offset support in the select statement
- Utilities for Spring Batch
- All conditions now support conditional rendering with lambdas
- Select * support
- Union all support
- Fixed self joins
GitHub milestone: https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.0+
- Support for optional conditions
- Support for column comparison conditions
- Support for sub-queries in the update statement
- Support for expressions and constants in the select statement
- Support for function in the update statement
- Support group by after where