1. 程式人生 > >MyBatis對於Java物件裡的列舉型別處理

MyBatis對於Java物件裡的列舉型別處理

平時咱們寫程式實體類內或多或少都會有列舉型別屬性,方便嘛。但是mybatis裡怎麼處理他們的增刪改查呢?

要求:

插入的時候,會用列舉的定義插入資料庫,我們希望在資料庫中看到的是數字或者其他東西;

查詢的時候,資料庫的值可以自動轉換為我們對應的列舉值。

舉例,我有一個這樣的列舉型別:

public enum UserStatus {  
  
    /** 無效*/  
    DISABLED(0),  
    /** 有效 */  
    AVAILABLE(1);  
      
    private int status;  
      
    UserStatus(int status){  
        this.status = status;  
    }  
  
    public int getStatus() {  
        return status;  
    }  
      
}  

我們插入資料庫中,資料庫應該為我們儲存0或者1

我們可以使用mybatis自帶的列舉型別EnumOrdinalTypeHandler

舉例如下:

<insert id="addUser" parameterType="User">  
    INSERT INTO t_user(USER_ID,USER_NAME,LOGIN_NAME,  
    LOGIN_PASSWORD,USER_STATUS,CREATE_TIME,UPDATE_TIME)  
    VALUES(  
        #{user_id},  
        #{user_name},  
        #{login_name},  
        #{login_password},  
        #{user_status, typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},  
        #{create_time},  
        #{update_time}  
    )  
</insert>  

我們的UserStatus插入的時候是UserStatus.AVAILABLE

執行完畢後,看結果:

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

 

我們可以自定義這樣的一個EnumStatusHandler:

import java.sql.CallableStatement;  
import java.sql.PreparedStatement;  
import java.sql.ResultSet;  
import java.sql.SQLException;  
  
import org.apache.ibatis.type.BaseTypeHandler;  
import org.apache.ibatis.type.JdbcType;  
  
/** 
 * Mybatis自定義轉換型別 
 * @author ShuYangYang 
 * E-Mail:
[email protected]
* http://www.shuyangyang.com.cn * Date:2015年1月26日下午10:12:54 * */ public class EnumStatusHandler extends BaseTypeHandler<UserStatus> { private Class<UserStatus> type; private final UserStatus[] enums; /** * 設定配置檔案設定的轉換類以及列舉類內容,供其他方法更便捷高效的實現 * @param type 配置檔案中設定的轉換類 */ public EnumStatusHandler(Class<UserStatus> type) { if (type == null) throw new IllegalArgumentException("Type argument cannot be null"); this.type = type; this.enums = type.getEnumConstants(); if (this.enums == null) throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type."); } @Override public void setNonNullParameter(PreparedStatement ps, int i, UserStatus parameter, JdbcType jdbcType) throws SQLException { // baseTypeHandler已經幫我們做了parameter的null判斷 ps.setInt(i, parameter.getStatus()); } @Override public UserStatus getNullableResult(ResultSet rs, String columnName) throws SQLException { // 根據資料庫儲存型別決定獲取型別,本例子中資料庫中存放INT型別 int i = rs.getInt(columnName); if (rs.wasNull()) { return null; } else { // 根據資料庫中的code值,定位EnumStatus子類 return locateEnumStatus(i); } } @Override public UserStatus getNullableResult(ResultSet rs, int columnIndex) throws SQLException { // 根據資料庫儲存型別決定獲取型別,本例子中資料庫中存放INT型別 int i = rs.getInt(columnIndex); if (rs.wasNull()) { return null; } else { // 根據資料庫中的code值,定位EnumStatus子類 return locateEnumStatus(i); } } @Override public UserStatus getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { // 根據資料庫儲存型別決定獲取型別,本例子中資料庫中存放INT型別 int i = cs.getInt(columnIndex); if (cs.wasNull()) { return null; } else { // 根據資料庫中的code值,定位EnumStatus子類 return locateEnumStatus(i); } } /** * 列舉型別轉換,由於建構函式獲取了列舉的子類enums,讓遍歷更加高效快捷 * @param code 資料庫中儲存的自定義code屬性 * @return code對應的列舉類 */ private UserStatus locateEnumStatus(int code) { for(UserStatus status : enums) { if(status.getStatus()==(Integer.valueOf(code))) { return status; } } throw new IllegalArgumentException("未知的列舉型別:" + code + ",請核對" + type.getSimpleName()); } }

mapper.xml裡這樣配置:

<resultMap type="User" id="userResult">  
……省略其他屬性配置  
        <result column="USER_STATUS" property="user_status" typeHandler="cn.com.hekliu.mybatis.EnumStatusHandler"/>  
……省略其他屬性配置  
    </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 2018, update_time=Mon Jan 26 21:17:09 CST 2018]]

 

完美結果。