mybatis关于枚举类的typeHandler

在mybatis作为持久层的项目中,如果我们的某个实体类属性有用到枚举类型,那么我们可以通过mybatis的typeHandler来处理,mybatis自带两个处理枚举的typeHandler类:EnumTypeHandler和EnumOrdinalTypeHandler。

先看一种情况:

public enum ResultStatus {

	SUCCESS,FAIL,ERROR;	
}

如果存放此结果状态值的数据库表设置的是字符varchar类型,那么存入到数据库的值就是SUCCESS、FAIL、ERROR这三种其中的一种。

假若此字段值在表中设置的是int类型,或者你想存入int类型,那么你就要为该枚举指定typeHandler了。由于我们用的是spring boot,所以就如下处理:

@Configuration
@MapperScan("com.bms.mapper")
public class MybatisPlusConfig {
	
	@Bean
	public PaginationInterceptor paginationInterceptor() {
		PaginationInterceptor page = new PaginationInterceptor();
		page.setDialectType("mysql");
		return page;
	}
	
	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource);
		sqlSessionFactoryBean.getObject().getConfiguration()
		.getTypeHandlerRegistry().register(ResultStatus.class, EnumOrdinalTypeHandler.class);
		return sqlSessionFactoryBean.getObject();
	}
}

这里要注意,我们注册的是EnumOrdinalTypeHandler类。

那么EnumTypeHandler和EnumOrdinalTypeHandler类有什么区别呢?

EnumTypeHandler存入数据库的是枚举的name,EnumOrdinalTypeHandler存入数据库的是枚举的位置,也就是下标,是从0开始的。

其实从EnumTypeHandler和EnumOrdinalTypeHandler的源代码就能看出。

介绍到这里,你或许会说,我不想用下标值来代替,我的枚举定义是这样的,我想存自定义的code:

public enum ResultStatus {

	SUCCESS(200,"成功"),FAIL(300,"失败"),ERROR(500,"其他错误");
	
	private Integer code;
	
	private String value;
	
	private ResultStatus(Integer code,String value) {
		this.code = code;
		this.value = value;
	}

	public Integer getCode() {
		return code;
	}

	public String getValue() {
		return value;
	}
	
	public static ResultStatus getResultByCode(Integer code) {
		switch (code) {
		case 200:
			return SUCCESS;
		case 300:
			return FAIL;
		case 500:
			return ERROR;
		default:
			return SUCCESS;
		}
	}
	
}

很好,这种情况下,我们就需要自定义typeHandler来处理了。

自定义typeHandler有两种方式:一种是继承BaseTypeHandler类,另一种是实现TypeHandler接口。我们先看第一种:

public class ResultTypeHandler extends BaseTypeHandler<ResultStatus>{

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, ResultStatus parameter, JdbcType jdbcType)
			throws SQLException {
		System.out.println("要保持的code========="+parameter.getCode()+"====="+parameter.getValue());
		ps.setString(i, parameter.getCode().toString());
	}

	@Override
	public ResultStatus getNullableResult(ResultSet rs, String columnName) throws SQLException {
		int code = rs.getInt(columnName);
		System.out.println("从数据库中取出的code============="+code);
		ResultStatus resultStatus = ResultStatus.getResultByCode(code);
		return resultStatus;
	}

	@Override
	public ResultStatus getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		int code = rs.getInt(columnIndex);
		System.out.println("从数据库中取出的code============="+code);
		ResultStatus resultStatus = ResultStatus.getResultByCode(code);
		return resultStatus;
	}

	@Override
	public ResultStatus getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		int code = cs.getInt(columnIndex);
		System.out.println("从数据库中取出的code============="+code);
		ResultStatus resultStatus = ResultStatus.getResultByCode(code);
		return resultStatus;
	}
}

第二种实现方式是:

public class CustomResultTypeHandler implements TypeHandler<ResultStatus>{

	/**
	 * 定义当前数据
	 */
	@Override
	public void setParameter(PreparedStatement ps, int i, ResultStatus parameter, JdbcType jdbcType) throws SQLException {
		System.out.println("要保存的code============="+parameter.getCode());
		ps.setString(i, parameter.getCode().toString());
	}

	@Override
	public ResultStatus getResult(ResultSet rs, String columnName) throws SQLException {
		int code = rs.getInt(columnName);
		System.out.println("从数据库中取出的code============="+code);
		ResultStatus resultStatus = ResultStatus.getResultByCode(code);
		return resultStatus;
	}

	@Override
	public ResultStatus getResult(ResultSet rs, int columnIndex) throws SQLException {
		int code = rs.getInt(columnIndex);
		System.out.println("从数据库中取出的code============="+code);
		ResultStatus resultStatus = ResultStatus.getResultByCode(code);
		return resultStatus;
	}

	@Override
	public ResultStatus getResult(CallableStatement cs, int columnIndex) throws SQLException {
		int code = cs.getInt(columnIndex);
		System.out.println("从数据库中取出的code============="+code);
		ResultStatus resultStatus = ResultStatus.getResultByCode(code);
		return resultStatus;
	}

}

可以看出两种方式很相似,除了要重写的方法名不一样。然后我们就需要注册我们自定义的typeHandler了。

@Configuration
@MapperScan("com.bms.mapper")
public class MybatisPlusConfig {
	
	@Bean
	public PaginationInterceptor paginationInterceptor() {
		PaginationInterceptor page = new PaginationInterceptor();
		page.setDialectType("mysql");
		return page;
	}
	
	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource);
		sqlSessionFactoryBean.getObject().getConfiguration()
		.getTypeHandlerRegistry().register(ResultStatus.class, CustomResultTypeHandler.class);
		return sqlSessionFactoryBean.getObject();
	}
}

通过以上步骤,我们在存储的时候,就能存储自定义的code了。在获取的时候,也能获取到code,然后通过code获取到整个枚举对象。

猜你喜欢

转载自my.oschina.net/yuhuixin/blog/1787987
今日推荐