竹山一叶

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

平时咱们写程序实体类内或多或少都会有枚举类型属性,方便嘛。但是mybatis里怎么处理他们的增删改查呢?

要求:

插入的时候,会用枚举的定义插入数据库,我们希望在数据库中看到的是数字或者其他东西;

查询的时候,数据库的值可以自动转换为我们对应的枚举值。

举例,我有一个这样的枚举类型:

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或者1

我们可以使用mybatis自带的枚举类型EnumOrdinalTypeHandler

举例如下:

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.AVAILABLE

执行完毕后,看结果:

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]]

 

完美结果。






posted on 2017-02-09 10:02  竹山一叶  阅读(19591)  评论(0编辑  收藏  举报