MyBatis對於Java物件裡的列舉型別處理
阿新 • • 發佈:2018-12-24
平時咱們寫程式實體類內或多或少都會有列舉型別屬性,方便嘛。但是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]]
完美結果。