MyBatis對於Java對象裏的枚舉類型處理

平時我們寫程序實體類內或多或少都會有枚舉類型屬性,方便嘛。可是mybatis裏怎麼處理他們的增刪改查呢?html

要求:java

插入的時候,會用枚舉的定義插入數據庫,咱們但願在數據庫中看到的是數字或者其餘東西;sql

查詢的時候,數據庫的值能夠自動轉換爲咱們對應的枚舉值。數據庫

舉例,我有一個這樣的枚舉類型:apache

Java Code 複製內容到剪貼板
  1. package cn.com.shuyangyang.domain;  
  2.   
  3. public enum UserStatus {  
  4.   
  5.     /** 無效*/  
  6.     DISABLED(0),  
  7.     /** 有效 */  
  8.     AVAILABLE(1);  
  9.       
  10.     private int status;  
  11.       
  12.     UserStatus(int status){  
  13.         this.status = status;  
  14.     }  
  15.   
  16.     public int getStatus() {  
  17.         return status;  
  18.     }  
  19.       
  20. }  

咱們插入數據庫中,數據庫應該爲咱們保存0或者1mybatis

咱們能夠使用mybatis自帶的枚舉類型EnumOrdinalTypeHandlerapp

舉例以下:dom

Java Code 複製內容到剪貼板
  1. <insert id="addUser" parameterType="User">  
  2.     INSERT INTO t_user(USER_ID,USER_NAME,LOGIN_NAME,  
  3.     LOGIN_PASSWORD,USER_STATUS,CREATE_TIME,UPDATE_TIME)  
  4.     VALUES(  
  5.         #{user_id},  
  6.         #{user_name},  
  7.         #{login_name},  
  8.         #{login_password},  
  9.         #{user_status, typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},  
  10.         #{create_time},  
  11.         #{update_time}  
  12.     )  
  13. </insert>  

咱們的UserStatus插入的時候是UserStatus.AVAILABLEide

執行完畢後,看結果:函數

DB.jpg

看,是否是結果是咱們指望的那樣。

可是問題來了?

咱們查詢的時候報錯了:Error querying database.  Cause: java.lang.IllegalArgumentException: No enum constant cn.com.shuyangyang.mybatis.UserStatus.1

咱們能夠自定義這樣的一個EnumStatusHandler:

Java Code 複製內容到剪貼板
  1. package cn.com.shuyangyang.mybatis;  
  2.   
  3. import java.sql.CallableStatement;  
  4. import java.sql.PreparedStatement;  
  5. import java.sql.ResultSet;  
  6. import java.sql.SQLException;  
  7.   
  8. import org.apache.ibatis.type.BaseTypeHandler;  
  9. import org.apache.ibatis.type.JdbcType;  
  10.   
  11. /** 
  12.  * Mybatis自定義轉換類型 
  13.  * @author ShuYangYang 
  14.  * E-Mail:shuyangyang@aliyun.com 
  15.  * http://www.shuyangyang.com.cn 
  16.  * Date:2015年1月26日下午10:12:54 
  17.  * 
  18.  */  
  19. public class EnumStatusHandler extends BaseTypeHandler<UserStatus> {  
  20.       
  21.     private Class<UserStatus> type;  
  22.        
  23.     private final UserStatus[] enums;  
  24.    
  25.     /** 
  26.      * 設置配置文件設置的轉換類以及枚舉類內容,供其餘方法更便捷高效的實現 
  27.      * @param type 配置文件中設置的轉換類 
  28.      */  
  29.     public EnumStatusHandler(Class<UserStatus> type) {  
  30.         if (type == null)  
  31.             throw new IllegalArgumentException("Type argument cannot be null");  
  32.         this.type = type;  
  33.         this.enums = type.getEnumConstants();  
  34.         if (this.enums == null)  
  35.             throw new IllegalArgumentException(type.getSimpleName()  
  36.                     + " does not represent an enum type.");  
  37.     }  
  38.   
  39.     @Override  
  40.     public void setNonNullParameter(PreparedStatement ps, int i,  
  41.             UserStatus parameter, JdbcType jdbcType) throws SQLException {  
  42.         // baseTypeHandler已經幫咱們作了parameter的null判斷  
  43.         ps.setInt(i, parameter.getStatus());  
  44.           
  45.     }  
  46.   
  47.     @Override  
  48.     public UserStatus getNullableResult(ResultSet rs, String columnName)  
  49.             throws SQLException {  
  50.         // 根據數據庫存儲類型決定獲取類型,本例子中數據庫中存放INT類型  
  51.         int i = rs.getInt(columnName);  
  52.            
  53.         if (rs.wasNull()) {  
  54.             return null;  
  55.         } else {  
  56.             // 根據數據庫中的code值,定位EnumStatus子類  
  57.             return locateEnumStatus(i);  
  58.         }  
  59.     }  
  60.   
  61.     @Override  
  62.     public UserStatus getNullableResult(ResultSet rs, int columnIndex)  
  63.             throws SQLException {  
  64.         // 根據數據庫存儲類型決定獲取類型,本例子中數據庫中存放INT類型  
  65.         int i = rs.getInt(columnIndex);  
  66.         if (rs.wasNull()) {  
  67.             return null;  
  68.         } else {  
  69.             // 根據數據庫中的code值,定位EnumStatus子類  
  70.             return locateEnumStatus(i);  
  71.         }  
  72.     }  
  73.   
  74.     @Override  
  75.     public UserStatus getNullableResult(CallableStatement cs, int columnIndex)  
  76.             throws SQLException {  
  77.         // 根據數據庫存儲類型決定獲取類型,本例子中數據庫中存放INT類型  
  78.         int i = cs.getInt(columnIndex);  
  79.         if (cs.wasNull()) {  
  80.             return null;  
  81.         } else {  
  82.             // 根據數據庫中的code值,定位EnumStatus子類  
  83.             return locateEnumStatus(i);  
  84.         }  
  85.     }  
  86.       
  87.     /** 
  88.      * 枚舉類型轉換,因爲構造函數獲取了枚舉的子類enums,讓遍歷更加高效快捷 
  89.      * @param code 數據庫中存儲的自定義code屬性 
  90.      * @return code對應的枚舉類 
  91.      */  
  92.     private UserStatus locateEnumStatus(int code) {  
  93.         for(UserStatus status : enums) {  
  94.             if(status.getStatus()==(Integer.valueOf(code))) {  
  95.                 return status;  
  96.             }  
  97.         }  
  98.         throw new IllegalArgumentException("未知的枚舉類型:" + code + ",請覈對" + type.getSimpleName());  
  99.     }  
  100.   
  101. }  

mapper.xml裏這樣配置:

XML/HTML Code 複製內容到剪貼板
  1. <resultMap type="User" id="userResult">  
  2. ……省略其餘屬性配置  
  3.         <result column="USER_STATUS" property="user_status" typeHandler="cn.com.shuyangyang.mybatis.EnumStatusHandler"/>  
  4. ……省略其餘屬性配置  
  5.     </resultMap>  

如今來看看結果:

 [User [user_id=782cba19-559f-41c3-a1b0-25fcac4cf118, user_name=系統管理員, login_name=admin, login_password=admin,user_status=AVAILABLE, create_time=Mon Jan 26 21:17:09 CST 2015, update_time=Mon Jan 26 21:17:09 CST 2015]]

 

完美結果。




相關文章
相關標籤/搜索