分享

mybatis自定义枚举转换类

 KILLKISS 2014-05-13
摘要 mybatis自定义枚举转换类的实现示例。

     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。

自定义转换类

01package com.sg.util.typehandler;
02 
03import java.sql.CallableStatement;
04import java.sql.PreparedStatement;
05import java.sql.ResultSet;
06import java.sql.SQLException;
07 
08import org.apache.ibatis.type.BaseTypeHandler;
09import org.apache.ibatis.type.JdbcType;
10 
11import com.sg.bean.EnumStatus;
12 
13/**
14 * 自定义EnumStatus转换类 <br>
15 * 存储属性:EnumStatus.getCode() <br>
16 * JDBCType:INT
17 * @author yanlei
18 */
19public 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}


枚举类

01package com.sg.bean;
02 
03 
04public enum EnumStatus {
05    NORMAL(1"正常"),
06    DELETE(0"删除"),
07    CANCEL(2"注销");
08     
09    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}


实体类

01package com.sg.bean;
02 
03 
04public class User {
05 
06    private String id;
07     
08    private String accountID;
09     
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配置文件

01<?xml version="1.0" encoding="UTF-8" ?>
02<!DOCTYPE mapper
03  PUBLIC "-////DTD Mapper 3.0//EN"
05<mapper namespace="com.sg.bean.User">
06 
07  <resultMap type="User" id="userMap">
08    <id column="id" property="id"/>
09    <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>


数据库脚本
1CREATE 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='用户表';

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多