用typehandler优雅的解决枚举类型的读写

Posted bruce128

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用typehandler优雅的解决枚举类型的读写相关的知识,希望对你有一定的参考价值。

问题

  1. 当数据库表字段是枚举类型的码值的时候,往往要根据字段注释找对应的业务值。随着业务的发展,产生了新的码值,而数据库表的注释往往不会跟着变。新的码值的业务含义就很难知道了。
  2. 对应的DO类的字段亦是如此。有了新的码值,字段的注释一般跟不上。

解决办法

表字段是码值的时候,一般会有一个枚举(enum)类对应。我们可以把DO类的对应字段定义为枚举类型,用mybatis的typehandler来处理读写。
这样做之后,就只需要维护枚举类型,数据库字段和DO类的注释都不需要了。最好的注释就是对应的枚举类
通过枚举类强管控码值的变化,就不会随着时间的推移,代码的可读性和可维护性大大降低了。

具体做法

1 枚举字段类型定义, 我们的目标是直接把这个类型入库,并正确的读取出来。

public enum TerminalEnum 
	
	HTTP("http", "http接口"),
	DUBBO("dubbo", "dubbo接口"),
	WEB("web", "网页"),
	;
	
	TerminalEnum(String t, String n) 
		this.type = t;
		this.name = n;
	
	
	@Override
	public String toString() 
		return this.name;
	
	
	@Getter
	private String type;
	@Getter
	private String name;
	
	public static TerminalEnum getEnumByType(String type) 
		TerminalEnum[] values = TerminalEnum.values();
		for (TerminalEnum terminalEnum : values) 
			if (StringUtils.equalsIgnoreCase(type, terminalEnum.type)) 
				return terminalEnum;
			
		
		return null;
	


2 typehandler定义, 需要继承 org.apache.ibatis.type.BaseTypeHandler

读写的逻辑

  1. 写的时候取枚举的type字段
  2. 读的时候根据type字段转成枚举类型
public class TerminalEnumHandler extends BaseTypeHandler<TerminalEnum> 
	
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, TerminalEnum terminalEnum, JdbcType jdbcType) throws SQLException 
		if (terminalEnum == null) 
			return;
		
		
		// 入库的时候取枚举的type字段
		ps.setString(i, terminalEnum.getType());
	
	
	@Override
	public TerminalEnum getNullableResult(ResultSet rs, String columnName) throws SQLException 
		String type = rs.getString(columnName);
		if (StringUtils.isBlank(type)) 
			return null;
		 else 
			// 读的时候根据type字段转成枚举类型
			return TerminalEnum.getEnumByType(type);
		
	
	
	@Override
	public TerminalEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException 
		String type = rs.getString(columnIndex);
		if (StringUtils.isBlank(type)) 
			return null;
		 else 
			return TerminalEnum.getEnumByType(type);
		
	
	
	@Override
	public TerminalEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException 
		String type = cs.getString(columnIndex);
		if (StringUtils.isBlank(type)) 
			return null;
		 else 
			return TerminalEnum.getEnumByType(type);
		
	

3 我的应用不需要手动注册这个typehandler
4 resultMap对应的字段加上typehandler

<resultMap id="BaseResultMap" type="com.***.***DO" >
... ... 
	<result column="terminal" property="terminal"  typeHandler="com.***.typehandler.TerminalEnumHandler"/>
</resultMap>

5 insert或者update的时候需要在字段后面带上typehandler

	<update id="updateTerminal" >
		UPDATE  ***_token
		SET
		terminal=#terminal, typeHandler=com.***.typehandler.TerminalEnumHandler
		WHERE id=#id
	</update>

以上是关于用typehandler优雅的解决枚举类型的读写的主要内容,如果未能解决你的问题,请参考以下文章

用typehandler优雅的解决枚举类型的读写

用typehandler优雅的解决数据库码值类型的读写

mybatis-枚举类型的typeHandler

关于Mybatis中使用自定义类型通过 自定义TypeHandler类型处理器进行类型转换的两种配置方案-枚举类型示例

jdbc如何优雅的解决字典表数据转化

Mybatis 3.4.4 升级到3.4.5+版本导致读写操作的时候使用不同的TypeHandler的解决方案