竹山一叶

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

转载自:http://my.oschina.net/SEyanlei/blog/188919


           mybatis提供了EnumTypeHandler和EnumOrdinalTypeHandler完成枚举类型的转换,两者的功能已经基本满足了日常的使用。但是可能有这样的需求:由于某种原因,我们不想使用枚举的name和ordinal作为数据存储字段。mybatis的自定义转换类出现了。


前提知识

           

           1. mybatis废弃了ibatis的TypeHandlerCallback接口,取而代之的接口是TypeHandler,它与原来的接口略有不同,但是方法类似。(见说明 https://code.google.com/p/mybatis/wiki/DocUpgrade3

           2. BaseTypeHandler是mybatis提供的基础转换类,该类实现了TypeHandler接口并提供很多公用方法,建议每个自定义转换类都继承它。

示例

           

           使用一段代码,将枚举类EnumStatus中的code属性存储到数据库对应字段statusCustom。


自定义转换类

  1. package com.sg.util.typehandler;  
  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. import com.sg.bean.EnumStatus;  
  12.   
  13. /** 
  14.  * 自定义EnumStatus转换类 <br> 
  15.  * 存储属性:EnumStatus.getCode() <br> 
  16.  * JDBCType:INT 
  17.  * @author yanlei 
  18.  */  
  19. public class EnumStatusHandler extends BaseTypeHandler<EnumStatus> {  
  20.   
  21.     private Class<EnumStatus> type;  
  22.   
  23.     private final EnumStatus[] enums;  
  24.   
  25.     /** 
  26.      * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现 
  27.      * @param type 配置文件中设置的转换类 
  28.      */  
  29.     public EnumStatusHandler(Class<EnumStatus> 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 EnumStatus getNullableResult(ResultSet rs, String columnName) throws SQLException {  
  41.         // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型  
  42.         int i = rs.getInt(columnName);  
  43.           
  44.         if (rs.wasNull()) {  
  45.             return null;  
  46.         } else {  
  47.             // 根据数据库中的code值,定位EnumStatus子类  
  48.             return locateEnumStatus(i);  
  49.         }  
  50.     }  
  51.   
  52.     @Override  
  53.     public EnumStatus getNullableResult(ResultSet rs, int columnIndex) throws SQLException {  
  54.         // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型  
  55.         int i = rs.getInt(columnIndex);  
  56.         if (rs.wasNull()) {  
  57.             return null;  
  58.         } else {  
  59.             // 根据数据库中的code值,定位EnumStatus子类  
  60.             return locateEnumStatus(i);  
  61.         }  
  62.     }  
  63.   
  64.     @Override  
  65.     public EnumStatus getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {  
  66.         // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型  
  67.         int i = cs.getInt(columnIndex);  
  68.         if (cs.wasNull()) {  
  69.             return null;  
  70.         } else {  
  71.             // 根据数据库中的code值,定位EnumStatus子类  
  72.             return locateEnumStatus(i);  
  73.         }  
  74.     }  
  75.   
  76.     @Override  
  77.     public void setNonNullParameter(PreparedStatement ps, int i, EnumStatus parameter, JdbcType jdbcType)  
  78.             throws SQLException {  
  79.         // baseTypeHandler已经帮我们做了parameter的null判断  
  80.         ps.setInt(i, parameter.getCode());  
  81.   
  82.     }  
  83.       
  84.     /** 
  85.      * 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷 
  86.      * @param code 数据库中存储的自定义code属性 
  87.      * @return code对应的枚举类 
  88.      */  
  89.     private EnumStatus locateEnumStatus(int code) {  
  90.         for(EnumStatus status : enums) {  
  91.             if(status.getCode().equals(Integer.valueOf(code))) {  
  92.                 return status;  
  93.             }  
  94.         }  
  95.         throw new IllegalArgumentException("未知的枚举类型:" + code + ",请核对" + type.getSimpleName());  
  96.     }  
  97.   
  98. }  

枚举类

  1. package com.sg.bean;  
  2.   
  3.   
  4. public enum EnumStatus {  
  5.     NORMAL(1"正常"),  
  6.     DELETE(0"删除"),  
  7.     CANCEL(2"注销");  
  8.       
  9.     private EnumStatus(int code, String description) {  
  10.         this.code = new Integer(code);  
  11.         this.description = description;  
  12.     }  
  13.     private Integer code;  
  14.       
  15.     private String description;  
  16.   
  17.       
  18.     public Integer getCode() {  
  19.       
  20.         return code;  
  21.     }  
  22.   
  23.       
  24.     public String getDescription() {  
  25.       
  26.         return description;  
  27.     }  
  28. }  

实体类

  1. package com.sg.bean;  
  2.   
  3.   
  4. public class User {  
  5.   
  6.     private String id;  
  7.       
  8.     private String accountID;  
  9.       
  10.     private String userName;  
  11.       
  12.     private EnumStatus statusDef; //枚举属性,使用mybatis默认转换类  
  13.       
  14.     private EnumStatus statusOrdinal; //枚举属性,使用EnumOrdinalTypeHandler转换  
  15.       
  16.     private EnumStatus statusCustom; // 枚举属性,自定义枚举转换类  
  17.       
  18.     public String getId() {  
  19.         return id;  
  20.     }  
  21.   
  22.       
  23.     public void setId(String id) {  
  24.         this.id = id;  
  25.     }  
  26.   
  27.       
  28.     public String getAccountID() {  
  29.         return accountID;  
  30.     }  
  31.   
  32.       
  33.     public void setAccountID(String accountID) {  
  34.         this.accountID = accountID;  
  35.     }  
  36.   
  37.       
  38.     public String getUserName() {  
  39.         return userName;  
  40.     }  
  41.   
  42.       
  43.     public void setUserName(String userName) {  
  44.         this.userName = userName;  
  45.     }  
  46.   
  47.       
  48.     public EnumStatus getStatusDef() {  
  49.         return statusDef;  
  50.     }  
  51.   
  52.     public void setStatusDef(EnumStatus statusDef) {  
  53.         this.statusDef = statusDef;  
  54.     }  
  55.   
  56.     public EnumStatus getStatusOrdinal() {  
  57.         return statusOrdinal;  
  58.     }  
  59.   
  60.     public void setStatusOrdinal(EnumStatus statusOrdinal) {  
  61.         this.statusOrdinal = statusOrdinal;  
  62.     }  
  63.       
  64.     public EnumStatus getStatusCustom() {  
  65.         return statusCustom;  
  66.     }  
  67.   
  68.     public void setStatusCustom(EnumStatus statusCustom) {  
  69.         this.statusCustom = statusCustom;  
  70.     }  
  71.       
  72.     @Override  
  73.     public String toString() {  
  74.         StringBuffer str = new StringBuffer();  
  75.         str.append("id:");  
  76.         str.append(id);  
  77.         str.append("\n");  
  78.           
  79.         str.append("userName:");  
  80.         str.append(userName);  
  81.         str.append("\n");  
  82.           
  83.         str.append("statusDef:");  
  84.         str.append(statusDef.name());  
  85.         str.append("\n");  
  86.           
  87.         str.append("statusOrdinal:");  
  88.         str.append(statusOrdinal.name());  
  89.         str.append("\n");  
  90.           
  91.         str.append("statusCustom:");  
  92.         str.append(statusCustom.name());  
  93.         str.append("\n");  
  94.           
  95.         return str.toString();  
  96.     }  
  97.   
  98. }  

mybatis配置文件

  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper  
  3.   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
  4.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  5. <mapper namespace="com.sg.bean.User">  
  6.   
  7.   <resultMap type="User" id="userMap">  
  8.     <id column="id" property="id"/>  
  9.     <result column="accountID" property="accountID"/>  
  10.     <result column="userName" property="userName"/>  
  11.     <result column="statusDef" property="statusDef"/>  
  12.     <result column="statusOrdinal" property="statusOrdinal" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>  
  13.     <result column="statusCustom" property="statusCustom" typeHandler="com.sg.util.typehandler.EnumStatusHandler"/>  
  14.   </resultMap>  
  15.     
  16.   <select id="selectUser" resultMap="userMap">  
  17.     select * from t_user where id = #{id}  
  18.   </select>  
  19.     
  20.   <insert id="insertUser" parameterType="User">  
  21.     insert into t_user(id,accountID,userName,statusDef,statusOrdinal,statusCustom)   
  22.     values(  
  23.     #{id}, #{accountID}, #{userName},   
  24.     #{statusDef},  
  25.     #{statusOrdinal, typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},  
  26.     #{statusCustom, typeHandler=com.sg.util.typehandler.EnumStatusHandler}  
  27.     )  
  28.   </insert>  
  29. </mapper>  

数据库脚本
  1. CREATE TABLE `t_user` (  
  2.   `id` varchar(45) NOT NULL,  
  3.   `accountID` varchar(45) DEFAULT NULL,  
  4.   `userName` varchar(45) DEFAULT NULL,  
  5.   `statusDef` varchar(45) DEFAULT NULL,  
  6.   `statusOrdinal` varchar(45) DEFAULT NULL,  
  7.   `statusCustom` int(11) DEFAULT NULL,  
  8.   PRIMARY KEY (`id`)  
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';  






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