MyBatis学习笔记(8)------使用枚举

使用MyBatis提供的枚举处理器

sys_role 表中有一个字段 enabled,这个字段只有 1 和 0 两个可选值。在 SysRole 类中,使用 Integer enabled,这种情况下必须手动校验 enabled 的值。使用枚举可以更加轻松的进行校验。

新增 Enabled 枚举类:

public enum Enabled {

	disabled,//禁用
	enabled;//启用
}

枚举除了本身的字面值外,还可以通过枚举的 ordinal() 方法获取枚举值的索引。在这个枚举类中,disabled 对应索引 0,enabled 对应索引 1。

将 SysRole 中 enabled 类型修改为 enum:

public class SysRole {

	//	其它属性
	private Enabled enabled;
	
	// 其它getter和setter方法
	public Enabled getEnabled() {
		return enabled;
	}
	public void setEnabled(Enabled enabled) {
		this.enabled = enabled;
	}
}

在数据库中 enabled 字段的类型是 int,因此在和数据库进行交互的时候,不能直接使用枚举类型,需要将枚举值转换为数据库中的 int 类型。

MyBatis 在处理 Java 类型和数据库类型时,使用 TypeHandler(类型处理器)对这两者进行转换。MyBatis 为 java 和 数据库 JDBC 中的基本类型和常用的类型提供了 TypeHandler 接口的实现。

MyBatis 在启动时会加载所有的 JDBC 对应的类型处理器,在处理枚举类型时默认使用 org.apache.ibatis.type.EnumTypeHandler 处理器,这个处理器会将枚举类型转换为字符串类型的字面值并使用,对于 Enabled 而言便是 “disabled” 和 “enabled” 字符串。

除此之外,MyBatis 还提供了另外一个 org.apache.ibatis.type.EnumOrdinalTypeHandler 处理器,这个处理器使用枚举的索引进行处理,对于 Enabled 而言便是 0(disabled) 和 1(enabled) 。想使用这个处理器需要在 mybatis-config.xml 中添加如下配置:

	<typeHandlers>
		<typeHandler 
			javaType="tk.mybatis.simple.type.Enabled"
			handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
	</typeHandlers>

javaType 为要处理的类型,handler 为要使用的类型处理器。

测试方法:

	@Test
	public void testUpdateById() {
		SqlSession sqlSession = getSqlSession();
		
		try {
			RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
			//先查询出角色
			SysRole role = roleMapper.selectById(2L);
			//数据库中这个角色的enabled字段值为1,对应启用状态
			Assert.assertEquals(Enabled.enabled, role.getEnabled());
			//修改角色的enabled值为disabled,禁用状态
			role.setEnabled(Enabled.disabled);
			//执行更新
			roleMapper.updateById(role);
		} finally {
			// TODO: handle finally clause
			sqlSession.rollback();
			sqlSession.close();
		}
	}

控制台输出:

DEBUG [main] - ==>  Preparing: select id, role_name roleName, enabled, create_time 'createInfo.createTime', create_by 'createInfo.createBy' from sys_role where id = ? 
DEBUG [main] - ==> Parameters: 2(Long)
TRACE [main] - <==    Columns: id, roleName, enabled, createInfo.createTime, createInfo.createBy
TRACE [main] - <==        Row: 2, 普通用户, 1, 2019-01-06 10:36:27.0, 1
DEBUG [main] - <==      Total: 1
DEBUG [main] - ==>  Preparing: update sys_role set role_name = ?, enabled = ?, create_by = ?, create_time = ? where id = ? 
DEBUG [main] - ==> Parameters: 普通用户(String), 0(Integer), 1(Long), 2019-01-06 10:36:27.0(Timestamp), 2(Long)
DEBUG [main] - <==    Updates: 1

第7行可以看出,MyBatis 已将 Enabled 的 disabled 值转换为 0(Integer)。

使用自定义的类型处理器

如果数据库存储的字段值既不是枚举的字面值,也不是枚举的索引值,这种情况就需要自己来实现类型处理器了。

修改枚举类 Enabled :

package tk.mybatis.simple.type;

public enum Enabled {

	enabled(1),
	disabled(0);
	
	private final int value;
	
	private Enabled(int value) {
		this.value = value;
	}
	
	public int getValue() {
		return value;
	}
}

新增一个 EnabledTypeHandler 类,实现 TypeHandler 接口,泛型为 Enabled:

package tk.mybatis.simple.type;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

public class EnabledTypeHandler implements TypeHandler<Enabled> {
	
	private final Map<Integer, Enabled> enabledMap = new HashMap<Integer, Enabled>();
	
	public EnabledTypeHandler() {
		// TODO Auto-generated constructor stub
		//这里将Enabled枚举类中的枚举类型放入Map中,以它们的枚举值作为key
		for(Enabled enabled : Enabled.values()) {
			enabledMap.put(enabled.getValue(), enabled);
		}
	}

	/*
	 * 定义当前数据如何保存到数据库中
	 * @see org.apache.ibatis.type.TypeHandler#setParameter(java.sql.PreparedStatement, int, java.lang.Object, org.apache.ibatis.type.JdbcType)
	 */
	@Override
	public void setParameter(PreparedStatement ps, int i, Enabled parameter, JdbcType jdbcType) throws SQLException {
		// TODO Auto-generated method stub
		ps.setInt(i, parameter.getValue());
	}

	/*
	 * 从数据库中获取value
	 * @see org.apache.ibatis.type.TypeHandler#getResult(java.sql.ResultSet, java.lang.String)
	 */
	@Override
	public Enabled getResult(ResultSet rs, String columnName) throws SQLException {
		// TODO Auto-generated method stub
		Integer value = rs.getInt(columnName);
		return enabledMap.get(value);
	}

	@Override
	public Enabled getResult(ResultSet rs, int columnIndex) throws SQLException {
		// TODO Auto-generated method stub
		Integer value = rs.getInt(columnIndex);
		return enabledMap.get(value);
	}

	/*
	 * 处理存储过程结果集
	 * @see org.apache.ibatis.type.TypeHandler#getResult(java.sql.CallableStatement, int)
	 */
	@Override
	public Enabled getResult(CallableStatement cs, int columnIndex) throws SQLException {
		// TODO Auto-generated method stub
		Integer value = cs.getInt(columnIndex);
		return enabledMap.get(value);
	}

}

我将 Enabled 枚举类中的枚举类型放入了 Map 中,以它们的枚举值作为 key。也可以在 Enabled 类中写一个 getEnabledByValue 静态方法,通过枚举值取出枚举类型。

实现了 TypeHandler 接口的 4 个方法,第 1 个方法是写入数据库用的,后面 3 个方法作用都是从数据库返回的结果中,拿值进行转换。

写好类型处理器后,还需要在 mybatis-config.xml 中进行配置:

<typeHandlers>
	<typeHandler 
		javaType="tk.mybatis.simple.type.Enabled"
		handler="tk.mybatis.simple.type.EnabledTypeHandler"/>
</typeHandlers>

猜你喜欢

转载自blog.csdn.net/BZeHong/article/details/86830412
今日推荐