SoFunction
Updated on 2025-04-13

Iterative method implementation of Mybatis from version 3.4.0 to version 3.5.7

1. 3.4.0

1. Main functions enhancement

  • Added Cursor List method in SqlSession.
  • BatchExecutor and ReuseExecutor operations support transaction timeout processing, mainly to fix the case where SQL is not used by spring annotation @Transactional specified timeout
  • Better support for generics
  • Supports new Date and Time APIs for Java8 (JSR-310)
<T> Cursor<T> selectcursor(String statement);
<T> Cursor<T> selectcursor(string statement, object parameter);
<T> Cursor<T> selectcursor(string statement, Object parameter, RowBounds rowBounds);

2、selectCursor example

<select resultMap="results" resultOrdered="true">
	select * from employees order by id
</select>
// Get a list which can have millions of rows
Cursor<Employee> employees=("getEmployeeNestedCursor");

// Get an iterator on employees
Iterator<Employee> iter = ();

List<Employee> smallChunk = new ArrayList<>(10); while(()){
	// Fetch next 10 employees
	for(int i = 0; i<10 && (); i++){
		(());
	}
	doSomethingWithAlreadyFetchedEmployees(smallChunk);
	();
}

3. Incompatible changes

  • The Transaction interface has added a getTimeout() method. If you implement this interface, you need to pay special attention.
  • Annotation @options() parameter flushCache is used instead with enumeration.
  • Because support for transaction timeouts is increased, StatementHandler#prepare(Connection) is changed to StatementHander#prepare(Connection, Integer), and the latter parameter takes the transaction timeout time.
  • Added SqlSession#selectCursor, Executor#queryCursor, ResultSetHander#handleCursorResultsSets and StatementHandler#queryCursor interfaces. Pay special attention if there is any implementation.
public enum FlushCachePolicy {
	/** <code>false</code> for select statement;
	 *  <code>true</code> for insert/update/delete statement.
	 * */
	DEFAULT,
	/** Flushes cache regardless of the statement type. */ 
	TRUE,
	/** Does not flush cache regardless of the statement type. */ 
	FALSE
}

II. 3.4.1

1. Main functions enhancement

When compiled with the Java 8 -parameters option, parameters are allowed to be referenced by the name it declared. For details on the processing code, see ParamNameResolver.
~ You can omit the @Param annotation to specify the parameter name on the mapper class (the name in xml should be the same as the parameter name)
~ Turn on by default

According to JSR310's new API definition for date and time, add a type processor for month and year. See MonthTypeHandler and YearTypeHandler for details.

@Select The data type returned supports object array, see MapperAnnotationBuilder#getReturnType for details

 @Select("select * from users")
 User[] getUsers();

The logImpl configuration parameters support custom XML configuration and XMLConfigBuilder.

2. Fixed errors

  • Fixed that when columnPrefix is ​​specified in the xml mapping file, the resultMap referenced by the loop will also fill in the corresponding value of the grandfather object.
<resultMap  type="User">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<association property="superior" resultMap="user" columnPrefix="superior_"/>
</resultMap>

<select  parameterType="long" resultMap="user">
	select 1 as id, 'a' as name, 2 as superior_id, 'b' as superior_name from dual
</select>
User user = (1L);
  • Fixed a RuntimeException thrown when booting on IBM WebSphere Application Server 8.5.5.9.
  • Fix Cursor not being returned as @Select statement
    PS: 3.4.0 has added a method for selectCursor cursor to process query results, but @Select cannot be supported
  • Fixed a NullPointerException thrown when used with the Kylin JDBC driver.
  • Fixed RowBounds not available as a parameter for a select statement with return type Cursor.
Cursor<User> usersCursor = (
				"getAllUsers", null, new RowBounds(1, 3));
  • The Select statement @Param cannot be used as an associated nested selection statement.

III. 3.4.2

1. Main functions enhancement

  • Add returnInstanceForEmptyRow configuration to control the return of an empty object instead of null when all columns in the query result are null.
  • Supports default methods in the mapper interface.
  • TypeHandler supports recursive search.
  • @CacheNamespace annotation adds properties attributes.
Property[] properties() default {};
  • Allows to specify default values ​​on placeholders.
    PS: This function is disabled by default, and can be enabled using the -default-value=true configuration.
  • Added a new type processor defined by JSR310 1.0.2.

2. Fixed errors

  • The default value of aggressiveLazyLoading is changed to false.
  • An exception is thrown when the field specified with keyProperty is not found.
@Options(useGeneratedKeys = true, keyProperty = "id")

IV. 3.4.3

1. Main functions enhancement

  • Adds the public interface registration type handler for enumeration.
    /mybatis/mybatis-3/pull/947
  • In MapperAnnotationBuilder, Jdbc3KeyGenerator and NoKeyGenerator share their own same instance. For details, see MapperAnnotationBuilder#parseStatement.
  • You can build update … join statements through SQL Builder.
    ~ The following code 3.4.3 has not been effective before
new SQL()
.UPDATE("table_1 a")
.INNER_JOIN("table_2 b USING (ID)")
.SET(" = ");

2. Fixed errors

  • Fixed the method on the grandpa mapper interface not found.
    ~ In the following code, the methods in the super_super_a interface cannot be traversed in versions before 3.4.3.
public interface a extends super_a
public interface super_a extends super_super_a
  • Fixed an error in placing the instance object in "LANGUAGE_DRIVER_MAP" instead of in "Driver" object when LanguageDriver is null. See LanguageDriverRegistry for details.
  • Fixed that boolean values ​​cannot be mapped to get and is at the same time.
  • Solve the problem of excessive memory allocation for parsing nested results.
  • Fixed the case where the default interface method only supports public.
    ~ The following code 3.4.3 was not supported before, because Mapper is a package-level access permission
@Mapper
interface Mapper extends SupperMapper{
	
	@Select("select * from login_user")
	Cursor<Map<String, Object>> select();
	
	@Select("select id from login_user")
	Integer[] selectIds();

	default List<Map<String, Object>> defaultGetUser(){
			return selectList();
	}
}

Fixed automatic mapping that should not appear between resultMap and as aliases.
/mybatis/mybatis-3/pull/1100~ For ≤ 3.4.2, even if the field map is clearly defined in the result map, even if the field in the SQL statement does not match the field defined in the map, the field will be automatically mapped.
~ For ≥ 3.4.3, automatic mapping does not apply to properties that are explicitly mapped in the result map.

In the following code, the phone returns null after version 3.4.3.

<resultMap  type="User">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<result property="phone" column="phone_number"/>
</resultMap>

<select  resultMap="user">
	select id, name, phone_number as phoneNumber from user where id = 1
</select>

V. 3.4.4

1. Main functions enhancement

  • No feature update, only fixed a bug in JAR on Meven Central in version 3.4.3.

VI, 3.4.5

1. Main functions enhancement

  • You can customize the default TypeHandler for enum. See EnumOrdinalTypeHandler for details.
  • ProviderContext is supported on the sql provider method for building a general mapper.
  • Merge the type handler for JSR-310 (Java Date and Time API) into the master.
  • Allows replacement of the property configuration on ProviderSqlSource in the sql provider.
<properties>
	<property name="Constants.LOGICAL_DELETE_OFF" value="false"/>
</properties>
public String buildSql(@Param("name") final String name){
	return new SQL(){{
		SELECT("*");
		FROM("test");
		if(name != null){
			WHERE("name = #{name}");
		}
		WHERE("logical_delete = #{Constants.LOGICAL_DELETE_OFF}");
	}}.toString();
}

2. Fixed errors

  • Fixed that when performing insert or update between two selects, not all select results are processed.
<select  resultMap="userResult,groupsResult">
	select * from mbtest.order_detail;
	insert into mbtest.order_detail (order_id, line_number) values (1, 132);
	select * from mbtest.order_header;
</select>
  • Delayed loading cannot override the attribute values ​​set by the user.
    /mybatis/mybatis-3/issues/988
  • Fixed an error in mapping with integer when using size as property name.
    The following code does not work properly before version 3.4.5
@Insert("INSERT INTO test(number, size) VALUES(#{number}, #{size})")
public void insert(@Param("number") long number, @Param("size") long size);
  • Fixed useGeneratedKeys=true in PostgreSQL, and when the 'id' specified by keyProperty does not have a setter, an ExecutorException is thrown.
  • Fixed using foreach tags to pollute global context.
    The following code where item=status will pollute status in and status =#{status}
<select>
	select * from tb
	<where>
		<if test="status != null">
			and status = #{status}
		</if>
		<if test="statusList != null">
			and status in
			<foreach collection="statusList" item="status", open="(" separator="," close=")">
				#{status}
			</foreach>
		</if>
	</where>
</select>

VII. 3.4.6

1. Main functions enhancement

  • Apply a custom ResultHandler to the return of the cursor type.
    /mybatis/mybatis-3/issues/493
  • BatchExecutor closes its statement immediately after iterating over and executing the SQL statement.
  • When parsing the xml file fails, add the resource path to the exception message.
  • @SelectProvider annotation supports static methods, see ProviderSqlSource for details.
    ~ The following code
@SelectProvider(type=, method="selectIds")
Integer[] selectIds();

class SqlGenerator{
	public static String selectIds(){
			return "select id from login_user";
	}
}
  • ProviderSqlSource supports returning CharSequence when constructing SQL statements.
@SelectProvider(type=, method="selectIds")
Integer[] selectIds();

class SqlGenerator{
	public static CharSequence selectIds(){
			return "select id from login_user";
	}
}
  • Placeholders in include can be replaced.
    ~ The following code was invalid before version 3.4.6 and cannot fill in the sql identified by include
<select  resultType="" resultOrdered="true">
	select
	<include ref>
		<property name="value" value="y"/>
	</include>
	from login_user
</select>

<sql >
   <if test="'${value}' == 'x'">
   	*
   </if>
   <if test="'${value}' == 'y'">
   	id
   </if>
</sql>

2. Fixed errors

  • Fixed the ClassCastException exception occurred when a custom HashMap type processor was detected.
    /mybatis/mybatis-3/commit/9233556404a3b6cc122d42c8ce0c97ba9e01b7ce
  • Fixed errors in serializing and deserializing cached data that resulted in NullPointerException.
  • Fixed the problem that TypeHandler cannot be registered after calling. See TypeHandlerRegistry for details.

8. 3.5.0

1. Main functions enhancement

  • Avoid "Illegal Reflective Access" warnings on JDK 9+.
  • Add an automatic module name.
  • Supports return value as an executor.
public interface UserMapper{

	@Select("select * from users where id = #{id}")
	Optional<User> findOne(Integer id);
}
  • Move the wasNull judgment in BaseTypeHandler to a subclass to do it.
    /mybatis/mybatis-3/pull/1244
  • The constructor tag in xml supports columnPrefix.
<resultMap  type="Author">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
</resultMap>

<resultMap  type="Article">
	<constructor>
		<idArg column="id" javaType="int"/>
		<arg column="name" javaType="String"/>
		<arg resultMap="authorRM" columnPrefix="author_" javaType="Author"/>
		<arg resultMap="authorRM" columnPrefix="coauthor_" javaType="Author"/>
	</constructor>
</resultMap>
  • Improve the performance of finding TypeHandler's automatic mapping results.
  • An exception is thrown when the key specified by keyProperty is not found.
  • A new SqlxmlTypeHandler type processor is added to convert sqlxml to string. See SqlxmlTypeHandler for details.
  • Tags can directly follow commas after sql statements.
-- Version3.5.0Previous writing --
&lt;set&gt;
	&lt;if test="name != null"&gt;
		name = #{name}
	&lt;/if&gt;
	&lt;if test="desc != null"&gt;
		,desc = #{desc}
	&lt;/if&gt;
&lt;/set&gt;

-- Version3.5.0How to write later --
&lt;set&gt;
	&lt;if test="name != null"&gt;
		name = #{name},
	&lt;/if&gt;
	&lt;if test="desc != null"&gt;
		desc = #{desc}
	&lt;/if&gt;
&lt;/set&gt;
  • Run private, package private, and protected properties on OGNL access expressions.
@Getter
public class Point{
	private int lid;
	private int x;
	private int y;
}
<insert >
	insert into points (lid, x, y) values
	<foreach item="point" separator=",">
		(#{}, #{}, #{})
	</foreach>
</insert>
  • Use tags in mapper xml If the resultType is not specified, it will be automatically retrieved from the type of the resultMap tag.
<resultMap type="Owner" >
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<discriminator javaType="String" column="vehicle_id">
		<case value="car">
			<association property="vehicle" column="vehicle_id" select=""/>
		</case>
	</discriminator>
</resultMap>
  • Supports Log4J 2.6+.
  • Upgrade the test framework to JUnit 5.
  • Improved compatibility with drivers that only support JDBC 3 APIs.
  • Use @CacheNamespace at the same time and no exception is thrown again.

2. Fixed errors

  • Fixed the issue where OffsetDateTimeTypeHandler, OffsetTimeTypeHandler and ZonedDateTimeTypeHandler lost time zones.
  • repairCursorSQLException that occurs when used with Db2.
  • Fixed the failure to correctly parse common type parameters when the class hierarchy exceeds 3 levels.

3. Changes that are not backward compatible

  • Using Cursor in 3.5.0 requires a driver for the JDBC 4.1 API.
  • If usingCustomized type processor, need to check wasNull().
  • Correct the typo in (autoCommmit -> autoCommit).
  • keyProperty no longer has a default value.

9. 3.5.1

1. Main functions enhancement

  • Add LanguageDriver to ProviderSqlSource。
    /mybatis/mybatis-3/pull/1391
  • LONGVARCHAR's default type processor is changed from ClobTypeHandler to StringTypeHandler.
  • If you use @SelectProvider, the method name and the corresponding provider method name can be omitted.
@SelectProvider(type=)
Integer[] selectIds();

class SqlGenerator{
	public static CharSequence selectIds(){
			return "select id from login_user";
	}
}
  • ProviderContext supports the configured databaseId property value when constructing SQL statements.
interface DatabaseIdMapper{
	@SelectProvider(type=)
	String selectDatabaseId();
}

class SqlProvider{
	public static String providerSql(ProviderContext context){
		if("hsql".equals(())){
			return "select " + () + " from user";
		} else{
			return "select " + () + " from user";
		}
	}
}

2. Fixed errors

  • Fixed the LocalTimeTypeHandler missing fractional seconds part.
  • Fixed some exceptions for LocalDateTypeHandler and LocalDateTimeTypeHandler to handle dates.
  • Fixed the keyProperty errors when batch insertion is specified with parameter name.
    ~ keyProperty = "" will report an error in batch insertion.
@Options(useGeneratedKeys = true, keyProperty="" keyColumn="id")
int insert(@Param("n") User user);
  • Fixed an error in which the type processor could not be found when there is an implementation method in the enum value.

3. Changes that are not backward compatible

LocalDateTypeHandler, LocalTimeTypeHandler, and LocalDateTimeTypeHandler are only valid for JDBC drivers that support the JDBC 4.2 API.

10, 3.5.2

1. Main functions enhancement

  • sql builder supports LIMIT, OFFSET and FETCH FIRST.
  • Add value attribute to Provider annotation, such as InsertProvider.
  • Support array objects as parameters.
    /mybatis/mybatis-3/pull/1548
  • SQL builder supports multi-line insertion syntax.
public void insert(){
	final String sql = new SQL(){{
		.INSERT_INTO("user")
		.INTO_VALUES("id", "name")
		.ADD_ROW()
		.INTO_VALUES("#{id}", "#{name}")
	}}.toString();
}
  • When there is only a single parameter condition, any data type is allowed.

2. Fixed errors

Fixed the possible npe of the DefaultResultSetHandler.

11, 3.5.3

1. Main functions enhancement

  • Updated default method calls to support JDK 14+8.
  • Add value attribute to Provider annotation, such as InsertProvider.
  • getter/setter will only throw a ReflectionException when it is actually accessed.
  • Supports CDATA variables in tags.
<sql >
	<![CDATA[
		col_${suffix}
	]]>
</sql>

2. Fixed errors

Fixed an error if the next element is empty when iterating over Cursor.

12, 3.5.4

1. Main functions enhancement

Supports the use of @Arg and @Result annotations multiple times on the same method.

@Result(property="id", colum="id")
@Result(property="name", colum="name")
@Select("select * from user where id = #{id}")
User selectOne(int id);

2. Fixed errors

  • Fixed when automatically generating ids, if the hashCode method is rewritten, the corresponding hashCode method will no longer be called, otherwise npe will be thrown.
  • Fixed that TypeVariable resolution may be incorrect in TypeParameterResolver.
    /mybatis/mybatis-3/issues/1794
  • Solve race conditions in TypeHandlerRegistry.
    /mybatis/mybatis-3/issues/1819

Thirteen, 3.5.5

1. Main functions enhancement

Supports obtaining the data required by resultMap and columnPrefix in @One and @Many annotations.

2. Fixed errors

  • Fixed an IllegalArgumentException that @CacheNamespaceRef may appear.

14, 3.5.6

1. Main functions enhancement

  • Increase the SQL_SERVER_SNAPSHOT transaction isolation level to support MS SQL Server.
  • When no JEP-290 serialization filter is defined, a WARN-level message is logged on the deserialized object stream.
    ~/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66/mybatis/mybatis-3/pull/2079
  • Specify defaultSqlProviderType to support global configuration on some annotations of the sql provider @SelectProvider, @UpdateProvider, @InsertProvider and @DeleteProvider.

2. Fixed errors

  • Fixed the risk of using BlockingCache to generate OutOfMemoryError.
    /mybatis/mybatis-3/pull/2044
  • Fixed InvalidPathException thrown when parsing typeAliases elements using packages as sublabels.
    /mybatis/mybatis-3/issues/1974

15, 3.5.7

1. Main functions enhancement

Improve performance in jdk 8 environment.

This is the article about the iterative method implementation of Mybatis from version 3.4.0 to version 3.5.7. For more related content from version 3.4.0 to version 3.5.7, please search for my previous articles or continue browsing the related articles below. I hope you will support me in the future!