MyBatis 3.4.0 版本功能介紹
這裡只列舉部分重要的內容,詳細內容看官方說明
新增功能
1. Cursor 新增返回值型別為遊標的方法
當查詢大量(上百萬)資料的時候,使用遊標可以有效的減少記憶體使用,不需要一次性將所有資料得到,可以通過遊標逐個或者分批(逐個獲取一批後)處理。
SqlSession
中新增的 3 個遊標方法:
/**
* A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.
* @param <T> the returned cursor element type.
* @param statement Unique identifier matching the statement to use.
* @return Cursor of mapped objects
*/
<T> Cursor<T> selectCursor(String statement);
/**
* A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.
* @param <T> the returned cursor element type.
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @return Cursor of mapped objects
*/
<T> Cursor<T> selectCursor(String statement, Object parameter);
/**
* A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.
* @param <T> the returned cursor element type.
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param rowBounds Bounds to limit object retrieval
* @return Cursor of mapped objects
*/
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);
注意: 3.4.0 版本的遊標方法目前有個 bug,因此不支援 @Select
註解方式,在將來的 3.4.1 版本中會解決這個問題。
使用示例:
<select id="selectAll" resultType="tk.mybatis.springboot.model.City">
select * from city
</select>
xml 裡面沒有任何改變,在獲取值的地方有變化,例如使用介面:
Cursor<City> selectAll();
或者使用命名介面方式:
Cursor<City> cityList = sqlSession.selectCursor("selectAll");
得到結果後,使用方法如下:
Iterator<City> iterator = cityList.iterator();
while(iterator.hasNext()){
City c2 = iterator.next();
Assert.assertNotNull(c2);
Assert.assertNotNull(c2.getName());
Assert.assertNotNull(c2.getState());
}
巢狀查詢的情況
當使用巢狀查詢時,還需要設定resultOrdered="true"
屬性,使用方法如下:
<select id="selectAll" resultMap="xx.CityMap" resultOrdered="true">
只有設定這個屬性才能得到當前物件 id
所對應的所有巢狀結果。
對某一個巢狀查詢,設定 resultOrdered="true"
的結果:
不設定的結果:
以上圖為例,判斷是否為同一個結果下的物件,使用 id 判斷的,這個 id 必須是 <resultMap>
中的 <id>
,另外為了結果完整,你還需要按照 <id>
配置的列進行排序,如果結果不是 <id>
對應列的順序,巢狀的結果數量會出錯。
2. 增加對 Java 8 日期(JSR-310)的支援
新增以下依賴:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-typehandlers-jsr310</artifactId>
<version>1.0.0</version>
</dependency>
如果你使用的 3.4.0 版本,就不需要任何配置就可以直接用。
如果你使用的老版本,需要手動配置:
<typeHandlers>
<typeHandler handler="org.apache.ibatis.type.InstantTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.LocalDateTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.LocalTimeTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.OffsetDateTimeTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.OffsetTimeTypeHandler" />
<typeHandler handler="org.apache.ibatis.type.ZonedDateTimeTypeHandler" />
</typeHandlers>
有關 mybatis-typehandlers-jsr310 專案的詳細資訊看這裡
3. 新增 autoMappingUnknownColumnBehavior 引數
新增了一個 settings 配置的引數 autoMappingUnknownColumnBehavior
,當檢測出未知列(或未知屬性)時,如何處理,預設情況下沒有任何提示,這在測試的時候很不方便,不容易找到錯誤。
可選值:
- NONE : 不做任何處理 (預設值)
- WARNING : 警告日誌形式的詳細資訊
- FAILING : 對映失敗,丟擲異常和詳細資訊
配置時,在 <settings>
裡面新增:
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
4. Sql Provider 註解方式支援多個引數
例如:
@SelectProvider(type = UserSqlBuilder.class, method = "buildGetUsersByName")
List<User> getUsersByName(
@Param("name") String name,
@Param("orderByColumn") String orderByColumn); // Multiple arguments
在寫 UserSqlBuilder
的時候,同樣需要使用註解來指定引數(或者按順序):
public String buildGetUsersByName(
@Param("name") final String name
@Param("orderByColumn") final String orderByColumn) { // Allow multiple arguments
return new SQL(){{
SELECT("*");
FROM("users");
if (name != null) {
WHERE("name like #{name} || '%'");
}
ORDER_BY(orderByColumn);
}}.toString();
}
解決的 BUG
支援實體類中的泛型型別
例如 Entity
基類:
public abstract class Entity<K extends Serializable> {
private static final long serialVersionUID = -1L;
protected K id;
public K getId() {
return id;
}
public void setId(K id) {
this.id = id;
}
其中一個子類:
public class User extends Entity<String>
在先前的版本中,MyBatis 無法獲取 id
的實際型別,導致找不到 TypeHandler
出錯。