在sys_role中有一个字段enabled,只有2个可选值,0-禁用,1-启用。在SysRole中使用了Integer enabled来定义,这种情况下必须手动校验enabled的值是否符合要求,在只有2个值的时候处理比较容易,但当值很多的时候,处理就比较麻烦。这时候就要使用Mybatis的枚举处理器。
1. 使用Mybatis提供的枚举处理器
Mybatis提供了2个枚举处理器:org.apache.ibatis.type.EnumTypeHandler和org.apache.ibatis.type.EnumOrdinalTypeHandler
- EnumTypeHandler处理器只对枚举的字面值进行处理,是Mybatis默认使用的。
- EnumOrdinalTypeHandler处理器是使用枚举的索引进行处理的。
在ex.mybatis.rbac.type包下增加枚举类型Enabled
public enum Enabled {
disabled, // 禁用
enabled; // 启用
}
在SysRole中修改enabled为枚举类型Enabled
// 枚举用法
private Enabled enabled;
public Enabled getEnabled() {
return enabled;
}
public void setEnabled(Enabled enabled) {
this.enabled = enabled;
}
在SysRoleMapper.xml中新增selectById和updateById方法
<!-- 枚举的用法 -->
<select id="selectById" resultMap="roleMap">
select id, role_name, enabled, create_by, create_time
from sys_role
where id = #{id}
</select>
<!-- 枚举的用法 -->
<update id="updateById">
update sys_role
<trim prefix="SET" suffixOverrides=",">
<if test="roleName != null and roleName != ''">
role_name = #{roleName,jdbcType=VARCHAR},
</if>
<if test="enabled != null">
enabled = #{enabled,jdbcType=INTEGER},
</if>
<if test="createBy != null and createBy != ''">
create_by = #{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<!-- 加上这个是为了防止所有字段都为空或部分不空时,SQL语句不会报错,set标签也解决不了全空值的问题 -->
id = #{id}
</trim>
where id = #{id}
</update>
在SysRoleMapper接口中新增selectById和updateById方法
/**
* 根据ID查询角色,枚举用法
* @param id
* @return
*/
SysRole selectById(Long id);
/**
* 根据ID更新角色,枚举用法
* @param id
* @return
*/
int updateById(SysRole role);
在RoleMaperTest中新增测试方法testUpdateById
@Test
public void testUpdateById() {
// 获取SqlSession
SqlSession sqlSession = openSession();
try {
// 获取SysRoleMapper接口
SysRoleMapper roleMapper = sqlSession.getMapper(SysRoleMapper.class);
// 调用selectById方法
SysRole role = roleMapper.selectById(1L);
System.out.println(role);
System.out.println(role.getEnabled() + ":" + Enabled.enabled);
role.setEnabled(Enabled.disabled);
// 调用updateById方法
int row = roleMapper.updateById(role);
System.out.println(row);
} finally {
sqlSession.rollback();
sqlSession.close();
}
}
测试结果(很意外的发现报错了,原因是使用了Mybatis默认的枚举处理器)
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'enabled' from result set. Cause: java.lang.IllegalArgumentException: No enum constant ex.mybatis.rbac.type.Enabled.1
### The error may exist in ex/mybatis/rbac/mapper/SysRoleMapper.xml
### The error may involve ex.mybatis.rbac.mapper.SysRoleMapper.selectById
### The error occurred while handling results
### SQL: select id, role_name, enabled, create_by, create_time from sys_role where id = ?
### Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'enabled' from result set. Cause: java.lang.IllegalArgumentException: No enum constant ex.mybatis.rbac.type.Enabled.1
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:77)
在mybatis_config.xml添加如下配置,指定另外一个处理器
<!-- 枚举类型的处理器 -->
<typeHandlers>
<typeHandler javaType="ex.mybatis.rbac.type.Enabled" handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
</typeHandlers>
再次运行,测试结果(更新成功)
[ex.mybatis.rbac.mapper.SysRoleMapper.selectById] - ==> Preparing: select id, role_name, enabled, create_by, create_time from sys_role where id = ?
[ex.mybatis.rbac.mapper.SysRoleMapper.selectById] - ==> Parameters: 1(Long)
[ex.mybatis.rbac.mapper.SysRoleMapper.selectById] - <== Columns: id, role_name, enabled, create_by, create_time
[ex.mybatis.rbac.mapper.SysRoleMapper.selectById] - <== Row: 1, 管理员, 1, 1, 2018-10-01 18:27:36.0
[ex.mybatis.rbac.mapper.SysRoleMapper.selectById] - <== Total: 1
SysRole [id=1, roleName=管理员, enabled=enabled, createBy=1, createTime=Mon Oct 01 18:27:36 CST 2018]
enabled:enabled
[ex.mybatis.rbac.mapper.SysRoleMapper.updateById] - ==> Preparing: update sys_role SET role_name = ?, enabled = ?, create_by = ?, create_time = ?, id = ? where id = ?
[ex.mybatis.rbac.mapper.SysRoleMapper.updateById] - ==> Parameters: 管理员(String), 0(Integer), 1(Long), 2018-10-01 18:27:36.0(Timestamp), 1(Long), 1(Long)
[ex.mybatis.rbac.mapper.SysRoleMapper.updateById] - <== Updates: 1
1