我们可以通过自定义TypeHandler的形式来在设置参数或 者取出结果集的时候自定义参数封装策略。
步骤:
-
实现TypeHandler接口或者继承BaseTypeHandler
-
使用@MappedTypes定义处理的java类型
使用@MappedJdbcTypes定义jdbcType类型
-
在自定义结果集标签或者参数处理的时候声明使用自定义 TypeHandler进行处理
或者在全局配置TypeHandler要处理的javaType,如下示例程序
示例程序
数据准备:
1
|
ALTER TABLE tbl_dept add column dept_status int(3);
|
一个代表部门状态的枚举类DeptStatus
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package com.eh.eden.mybatis.enums;
public enum DeptStatus implements IStatusEnum {
WORKING(100, "工作中"),
MEETING(100, "会议中"),
VOCATION(100, "休假中");
private int code;
private String desc;
DeptStatus(int code, String desc) {
this.code = code;
this.desc = desc;
}
@Override
public int getCode() {
return code;
}
@Override
public void setCode(int code) {
this.code = code;
}
public String getDesc() {
return desc;
}
}
|
IStatusEnum
1
2
3
4
5
6
7
8
9
|
package com.eh.eden.mybatis.enums;
public interface IStatusEnum<E> {
int getCode();
void setCode(int code);
}
|
StatusEnumUtil
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package com.eh.eden.mybatis.enums;
public class StatusEnumUtil {
public static <E extends Enum<E> & IStatusEnum<E>> E getEnumByCode(E e, int code) {
if (e == null) {
throw new RuntimeException("传入枚举类型不能为空");
}
return getEnumByCode((Class<E>) e.getClass(), code);
}
public static <E extends Enum<E> & IStatusEnum<E>> E getEnumByCode(Class<E> clazz, int code) {
try {
E[] es = clazz.getEnumConstants();
for (E e : es) {
if (code == e.getCode()) return e;
}
} catch (Exception e) {
throw new RuntimeException("枚举类型转换内部错误");
}
throw new RuntimeException(String.format("通过%s没有找到具体的枚举类型", String.valueOf(code)));
}
}
|
StatusEnumTypeHandler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
package com.eh.eden.mybatis.enums;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class StatusEnumTypeHandler<E extends Enum<E> & IStatusEnum<E>> extends BaseTypeHandler<E> {
private final Class<E> type;
public StatusEnumTypeHandler(Class<E> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
if (jdbcType == null) {
ps.setInt(i, parameter.getCode());
} else {
ps.setObject(i, parameter.name(), jdbcType.TYPE_CODE); // see r3589
}
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
Integer code = rs.getInt(columnName);
return code == null ? null : StatusEnumUtil.getEnumByCode(type, code);
}
@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Integer code = rs.getInt(columnIndex);
return code == null ? null : StatusEnumUtil.getEnumByCode(type, code);
}
@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Integer code = cs.getInt(columnIndex);
return code == null ? null : StatusEnumUtil.getEnumByCode(type, code);
}
}
|
mybatis-config.xml
1
2
3
4
|
<typeHandlers>
<typeHandler handler="com.eh.eden.mybatis.enums.StatusEnumTypeHandler"
javaType="com.eh.eden.mybatis.enums.IStatusEnum"/>
</typeHandlers>
|
DeptMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<resultMap id="dept" type="com.eh.eden.mybatis.orm.bean.Dept">
<id column="id" property="id"/>
<result column="dept_name" property="deptName"/>
<result column="dept_status" property="deptStatus"/>
</resultMap>
<insert id="insertSelective" parameterType="com.eh.eden.mybatis.orm.bean.Dept">
insert into tbl_dept
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="deptName != null">
dept_name,
</if>
<if test="deptStatus != null">
dept_status,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="deptName != null">
#{deptName,jdbcType=VARCHAR},
</if>
<if test="deptStatus != null">
#{deptStatus}
</if>
</trim>
</insert>
<select id="getDeptById" resultMap="dept">
select id, dept_name,dept_status from tbl_dept where id = #{id}
</select>
|
测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@Test
public void testTypeHandlerSelect() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
try (SqlSession session = sqlSessionFactory.openSession()
) {
DeptMapper deptMapper = session.getMapper(DeptMapper.class);
Dept dept = deptMapper.getDeptById(4);
System.out.println(dept);
}
}
@Test
public void testTypeHandlerInsert() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
try (SqlSession session = sqlSessionFactory.openSession(true)
) {
DeptMapper deptMapper = session.getMapper(DeptMapper.class);
deptMapper.insertSelective(new Dept(null, "人事部", null, DeptStatus.WORKING));
}
}
|