1. 程式人生 > >MyBatis中Mapper的返回值型別

MyBatis中Mapper的返回值型別

insert、update、delete語句的返回值型別

對資料庫執行修改操作時,資料庫會返回受影響的行數。

在MyBatis(使用版本3.4.6,早期版本不支援)中insert、update、delete語句的返回值可以是Integer、Long和Boolean。在定義Mapper介面時直接指定需要的型別即可,無需在對應的<insert><update><delete>標籤中顯示宣告。

對應的程式碼在 org.apache.ibatis.binding.MapperMethod 類中,如下:

  • 對於insert、update、delete語句,MyBatis都會使用 rowCountResult
    方法對返回值進行轉換;
  • rowCountResult 方法會根據Mapper宣告中方法的返回值型別來對引數進行轉換;
  • 對於返回型別為Boolean的情況,如果返回的值大於0,則返回True,否則返回False
 1 public Object execute(SqlSession sqlSession, Object[] args) {
 2     Object result;
 3     switch (command.getType()) {
 4       case INSERT: {
 5       Object param = method.convertArgsToSqlCommandParam(args);
6 result = rowCountResult(sqlSession.insert(command.getName(), param)); 7 break; 8 } 9 case UPDATE: { 10 Object param = method.convertArgsToSqlCommandParam(args); 11 result = rowCountResult(sqlSession.update(command.getName(), param)); 12 break;
13 } 14 case DELETE: { 15 Object param = method.convertArgsToSqlCommandParam(args); 16 result = rowCountResult(sqlSession.delete(command.getName(), param)); 17 break; 18 } 19 case SELECT: 20 if (method.returnsVoid() && method.hasResultHandler()) { 21 executeWithResultHandler(sqlSession, args); 22 result = null; 23 } else if (method.returnsMany()) { 24 result = executeForMany(sqlSession, args); 25 } else if (method.returnsMap()) { 26 result = executeForMap(sqlSession, args); 27 } else if (method.returnsCursor()) { 28 result = executeForCursor(sqlSession, args); 29 } else { 30 Object param = method.convertArgsToSqlCommandParam(args); 31 result = sqlSession.selectOne(command.getName(), param); 32 } 33 break; 34 case FLUSH: 35 result = sqlSession.flushStatements(); 36 break; 37 default: 38 throw new BindingException("Unknown execution method for: " + command.getName()); 39 } 40 if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) { 41 throw new BindingException("Mapper method '" + command.getName() 42 + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); 43 } 44 return result; 45 } 46 47 private Object rowCountResult(int rowCount) { 48 final Object result; 49 if (method.returnsVoid()) { 50 result = null; 51 } else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) { 52 result = rowCount; 53 } else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) { 54 result = (long)rowCount; 55 } else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) { 56 result = rowCount > 0; 57 } else { 58 throw new BindingException("Mapper method '" + command.getName() + "' has an unsupported return type: " + method.getReturnType()); 59 } 60 return result; 61 }

select語句的返回值型別

對於select語句,必須在Mapper對映檔案中顯示宣告返回值型別,否則會丟擲異常,指出“A query was run and no Result Maps were found for the Mapped Statement”。

select語句返回的column值與Mapper方法返回值的屬性的對映有兩種方式:

  • 通過名稱實現自動對映
  • 通過resultMap標籤指定對映方式

通過名稱實現自動對映

只要保證資料庫查詢返回的column名稱和Bean的屬性名一致,Mybatis便能夠實現自動對映。如:

    <select id="selectActorById"  resultType="canger.study.chapter04.bean.Actor">
        select actor_id as id, first_name as firstName ,last_name as lastName
        from actor
        where actor_id=#{id}
    </select>
public class Actor {
    Long id;
    String firstName;
    String lastName;
}

 需要特別說明的有3個地方:

  • 返回值Bean無需為屬性設定getter/setter方法,Mybatis依然能夠為其賦值;
  • 如果column名稱和Bean的屬性名只有部分相同,那麼只有名稱相同的屬性會被賦值,Bean依然會被建立;
  • 如果column名稱與所有Bean的屬性名都不相同,則select語句會返回null值,即使資料庫中存在符合查詢條件的記錄;

 通過resultMap標籤指定對映方式

待續