摘要
mybatis自定義枚舉轉(zhuǎn)換類(lèi)的實(shí)現(xiàn)示例。
mybatis提供了EnumTypeHandler和EnumOrdinalTypeHandler完成枚舉類(lèi)型的轉(zhuǎn)換,兩者的功能已經(jīng)基本滿足了日常的使用。但是可能有這樣的需求:由于某種原因,我們不想使用枚舉的name和ordinal作為數(shù)據(jù)存儲(chǔ)字段。mybatis的自定義轉(zhuǎn)換類(lèi)出現(xiàn)了。
前提知識(shí)
1. mybatis廢棄了ibatis的TypeHandlerCallback接口,取而代之的接口是TypeHandler,它與原來(lái)的接口略有不同,但是方法類(lèi)似。(見(jiàn)說(shuō)明 https://code.google.com/p/mybatis/wiki/DocUpgrade3)
2. BaseTypeHandler是mybatis提供的基礎(chǔ)轉(zhuǎn)換類(lèi),該類(lèi)實(shí)現(xiàn)了TypeHandler接口并提供很多公用方法,建議每個(gè)自定義轉(zhuǎn)換類(lèi)都繼承它。
示例
使用一段代碼,將枚舉類(lèi)EnumStatus中的code屬性存儲(chǔ)到數(shù)據(jù)庫(kù)對(duì)應(yīng)字段statusCustom。
自定義轉(zhuǎn)換類(lèi)
01 | package com.sg.util.typehandler; |
03 | import java.sql.CallableStatement; |
04 | import java.sql.PreparedStatement; |
05 | import java.sql.ResultSet; |
06 | import java.sql.SQLException; |
08 | import org.apache.ibatis.type.BaseTypeHandler; |
09 | import org.apache.ibatis.type.JdbcType; |
11 | import com.sg.bean.EnumStatus; |
14 | * 自定義EnumStatus轉(zhuǎn)換類(lèi) <br> |
15 | * 存儲(chǔ)屬性:EnumStatus.getCode() <br> |
19 | public class EnumStatusHandler extends BaseTypeHandler<EnumStatus> { |
21 | private Class<EnumStatus> type; |
23 | private final EnumStatus[] enums; |
26 | * 設(shè)置配置文件設(shè)置的轉(zhuǎn)換類(lèi)以及枚舉類(lèi)內(nèi)容,供其他方法更便捷高效的實(shí)現(xiàn) |
27 | * @param type 配置文件中設(shè)置的轉(zhuǎn)換類(lèi) |
29 | public EnumStatusHandler(Class<EnumStatus> type) { |
31 | throw new IllegalArgumentException( "Type argument cannot be null" ); |
33 | this .enums = type.getEnumConstants(); |
34 | if ( this .enums == null ) |
35 | throw new IllegalArgumentException(type.getSimpleName() |
36 | + " does not represent an enum type." ); |
40 | public EnumStatus getNullableResult(ResultSet rs, String columnName) throws SQLException { |
41 | // 根據(jù)數(shù)據(jù)庫(kù)存儲(chǔ)類(lèi)型決定獲取類(lèi)型,本例子中數(shù)據(jù)庫(kù)中存放INT類(lèi)型 |
42 | int i = rs.getInt(columnName); |
47 | // 根據(jù)數(shù)據(jù)庫(kù)中的code值,定位EnumStatus子類(lèi) |
48 | return locateEnumStatus(i); |
53 | public EnumStatus getNullableResult(ResultSet rs, int columnIndex) throws SQLException { |
54 | // 根據(jù)數(shù)據(jù)庫(kù)存儲(chǔ)類(lèi)型決定獲取類(lèi)型,本例子中數(shù)據(jù)庫(kù)中存放INT類(lèi)型 |
55 | int i = rs.getInt(columnIndex); |
59 | // 根據(jù)數(shù)據(jù)庫(kù)中的code值,定位EnumStatus子類(lèi) |
60 | return locateEnumStatus(i); |
65 | public EnumStatus getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { |
66 | // 根據(jù)數(shù)據(jù)庫(kù)存儲(chǔ)類(lèi)型決定獲取類(lèi)型,本例子中數(shù)據(jù)庫(kù)中存放INT類(lèi)型 |
67 | int i = cs.getInt(columnIndex); |
71 | // 根據(jù)數(shù)據(jù)庫(kù)中的code值,定位EnumStatus子類(lèi) |
72 | return locateEnumStatus(i); |
77 | public void setNonNullParameter(PreparedStatement ps, int i, EnumStatus parameter, JdbcType jdbcType) |
79 | // baseTypeHandler已經(jīng)幫我們做了parameter的null判斷 |
80 | ps.setInt(i, parameter.getCode()); |
85 | * 枚舉類(lèi)型轉(zhuǎn)換,由于構(gòu)造函數(shù)獲取了枚舉的子類(lèi)enums,讓遍歷更加高效快捷 |
86 | * @param code 數(shù)據(jù)庫(kù)中存儲(chǔ)的自定義code屬性 |
87 | * @return code對(duì)應(yīng)的枚舉類(lèi) |
89 | private EnumStatus locateEnumStatus( int code) { |
90 | for (EnumStatus status : enums) { |
91 | if (status.getCode().equals(Integer.valueOf(code))) { |
95 | throw new IllegalArgumentException( "未知的枚舉類(lèi)型:" + code + ",請(qǐng)核對(duì)" + type.getSimpleName()); |
枚舉類(lèi)
04 | public enum EnumStatus { |
07 | CANCEL( 2 , "注銷(xiāo)" ); |
09 | private EnumStatus( int code, String description) { |
10 | this .code = new Integer(code); |
11 | this .description = description; |
15 | private String description; |
18 | public Integer getCode() { |
24 | public String getDescription() { |
實(shí)體類(lèi)
08 | private String accountID; |
10 | private String userName; |
12 | private EnumStatus statusDef; //枚舉屬性,使用mybatis默認(rèn)轉(zhuǎn)換類(lèi) |
14 | private EnumStatus statusOrdinal; //枚舉屬性,使用EnumOrdinalTypeHandler轉(zhuǎn)換 |
16 | private EnumStatus statusCustom; // 枚舉屬性,自定義枚舉轉(zhuǎn)換類(lèi) |
18 | public String getId() { |
23 | public void setId(String id) { |
28 | public String getAccountID() { |
33 | public void setAccountID(String accountID) { |
34 | this .accountID = accountID; |
38 | public String getUserName() { |
43 | public void setUserName(String userName) { |
44 | this .userName = userName; |
48 | public EnumStatus getStatusDef() { |
52 | public void setStatusDef(EnumStatus statusDef) { |
53 | this .statusDef = statusDef; |
56 | public EnumStatus getStatusOrdinal() { |
60 | public void setStatusOrdinal(EnumStatus statusOrdinal) { |
61 | this .statusOrdinal = statusOrdinal; |
64 | public EnumStatus getStatusCustom() { |
68 | public void setStatusCustom(EnumStatus statusCustom) { |
69 | this .statusCustom = statusCustom; |
73 | public String toString() { |
74 | StringBuffer str = new StringBuffer(); |
79 | str.append( "userName:" ); |
83 | str.append( "statusDef:" ); |
84 | str.append(statusDef.name()); |
87 | str.append( "statusOrdinal:" ); |
88 | str.append(statusOrdinal.name()); |
91 | str.append( "statusCustom:" ); |
92 | str.append(statusCustom.name()); |
95 | return str.toString(); |
mybatis配置文件
01 | <? xml version = "1.0" encoding = "UTF-8" ?> |
03 | PUBLIC "-////DTD Mapper 3.0//EN" |
05 | < mapper namespace = "com.sg.bean.User" > |
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" /> |
16 | < select id = "selectUser" resultMap = "userMap" > |
17 | select * from t_user where id = #{id} |
20 | < insert id = "insertUser" parameterType = "User" > |
21 | insert into t_user(id,accountID,userName,statusDef,statusOrdinal,statusCustom) |
23 | #{id}, #{accountID}, #{userName}, |
25 | #{statusOrdinal, typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler}, |
26 | #{statusCustom, typeHandler=com.sg.util.typehandler.EnumStatusHandler} |
數(shù)據(jù)庫(kù)腳本
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 , |
9 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT= '用戶表' ; |
|