在系统中,有些类型、状态等特别多,代码中写了很多的逻辑判断。本文将枚举类和普通java数据类型的字段一样在mybatise中直接操作存入修改和查询返回,并且以整个项目考虑,适用于项目中存在大量的枚举类情形,不要觉得复杂内容长,不就是粘贴复制吗?超级简单好吧!如下xml中是对一个表的基本操作:
下面是含有枚举类属性的普通java类
public class ContractSignatureEntity extends BaseEntity {
/**
* 电子合同模板配置ID
*/
private Integer contractTemplateId;
/**
* 电子合同签署状态
*/
private SignatureStatus signatureStatus;get。。set..
}
一个普通的枚举类
public enum SignatureStatus implements EnumShow {
SIGN_CANCEL(-1, "已撤销", "已撤销"),
SIGN_ARCHIVED_FAILED(-7, "签署中", "归档失败"),
SIGN_ARCHIVED_SUCCESS(7, "已归档", "已归档");
private int value;
private String desc;
private String flowDesc;
SignatureStatus(int value, String desc, String flowDesc) {
this.value = value;
this.desc = desc;
this.flowDesc = flowDesc;
}
public static SignatureStatus forValue(int value) {
for (SignatureStatus signatureStatus : SignatureStatus.values()) {
if (signatureStatus.value == value) {
return signatureStatus;
}
}
return null;
}
/**
* 生成合同状态位
*
* @return
*/
public static List<SignatureStatus> getCanGenerateStatus() {
return Arrays.asList(INIT, SIGN_CANCEL);
}
/**
* 落公司章状态位
*
* @return
*/
public static List<SignatureStatus> getCanCompanySignStatus() {
return Arrays.asList(SIGN_PROCESSED_USER_SUCCESS, SIGN_PROCESSED_COM_FAILED);
}
@Override
public String getName() {
return name();
}
@Override
public int getValue() {
return value;
}
@Override
public String getDesc() {
return desc;
}
public String getFlowDesc() {
return flowDesc;
}
}EnumShow 提供给前端用的枚举名称,重写了枚举getName,如果前端不需要可以直接实现EnumBehaviour接口
public interface EnumShow extends EnumBehaviour {
String getName();
}我们有两个枚举类需要实现的接口,EnumBehaviour(int类型)和EnumStringBehaviour(varchar类型),本文示例是int类型的状态存到数据库,所以只需要枚举类实现EnumBehaviour接口即可。其实这样做只是将重写了相应方法的公共部分抽离出来,以便项目中的所有枚举类使用。
public interface EnumBehaviour {
int getValue();
String getDesc();
}public interface EnumStringBehaviour {
String getValue();
String getDesc();
}下面是关于自动与DB映射转换的两个类,将至直接复制到项目中,按照后面的配置配置就可以了
DB保存int类型的
public class EnumValueTypeHandler extends BaseTypeHandler<EnumBehaviour> {
private Class<EnumBehaviour> type;
private final EnumBehaviour[] enums;
/**
* 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
*
* @param type 配置文件中设置的转换类
*/
public EnumValueTypeHandler(Class<EnumBehaviour> type) {
if (type == null)
throw new IllegalArgumentException("Type argument cannot be null");
this.type = type;
this.enums = type.getEnumConstants();
if (this.enums == null)
throw new IllegalArgumentException(type.getSimpleName()
+ " does not represent an enum type.");
}
@Override
public EnumBehaviour getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
int i = rs.getInt(columnName);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位EnumBehaviour子类
return locateEnumBehaviour(i);
}
}
@Override
public EnumBehaviour getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
int i = rs.getInt(columnIndex);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位EnumBehaviour子类
return locateEnumBehaviour(i);
}
}
@Override
public EnumBehaviour getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
int i = cs.getInt(columnIndex);
if (cs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位EnumBehaviour子类
return locateEnumBehaviour(i);
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, EnumBehaviour parameter, JdbcType jdbcType)
throws SQLException {
// baseTypeHandler已经帮我们做了parameter的null判断
ps.setInt(i, parameter.getValue());
}
/**
* 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷
*
* @param code 数据库中存储的自定义code属性
* @return code对应的枚举类
*/
private EnumBehaviour locateEnumBehaviour(int code) {
for (EnumBehaviour status : enums) {
if (status.getValue() == code) {
return status;
}
}
throw new IllegalArgumentException("未知的枚举类型:" + code + ",请核对" + type.getSimpleName());
}
}DB保存varchar类型的
public class EnumStringValueTypeHandler extends BaseTypeHandler<EnumStringBehaviour> {
private Class<EnumStringBehaviour> type;
private final EnumStringBehaviour[] enums;
/**
* 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
*
* @param type 配置文件中设置的转换类
*/
public EnumStringValueTypeHandler(Class<EnumStringBehaviour> type) {
if (type == null)
throw new IllegalArgumentException("Type argument cannot be null");
this.type = type;
this.enums = type.getEnumConstants();
if (this.enums == null)
throw new IllegalArgumentException(type.getSimpleName()
+ " does not represent an enum type.");
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, EnumStringBehaviour parameter, JdbcType jdbcType) throws SQLException {
// baseTypeHandler已经帮我们做了parameter的null判断
ps.setString(i, parameter.getValue());
}
@Override
public EnumStringBehaviour getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放VARCHAR类型
String str = rs.getString(columnName);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位EnumBehaviour子类
return locateStringEnumBehaviour(str);
}
}
@Override
public EnumStringBehaviour getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放VARCHAR类型
String str = rs.getString(columnIndex);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位EnumBehaviour子类
return locateStringEnumBehaviour(str);
}
}
@Override
public EnumStringBehaviour getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放VARCHAR类型
String str = cs.getString(columnIndex);
if (cs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位EnumBehaviour子类
return locateStringEnumBehaviour(str);
}
}
/**
* 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷
*
* @param code 数据库中存储的自定义code属性
* @return code对应的枚举类
*/
private EnumStringBehaviour locateStringEnumBehaviour(String code) {
for (EnumStringBehaviour enumStringBehaviour : enums) {
if (enumStringBehaviour.getValue().compareTo(code) == 0) {
return enumStringBehaviour;
}
}
throw new IllegalArgumentException("未知的枚举类型:" + code + ",请核对" + type.getSimpleName());
}
}
下面是一个配置信息的xml,名字随便起,该xml配置了枚举类和想要映射到数据库的类型类的关系,一个int,一个varchar,也就是说你得告诉数据库你这个枚举放入数据库的值是啥吧?mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="tk.mybatis.springboot.model"/>
</typeAliases>
<typeHandlers>
<typeHandler handler="com.rrc.finance.utils.EnumValueTypeHandler" javaType="com.rrc.finance.order.core.common.enums.SignatureStatus"/>
<typeHandler handler="com.rrc.finance.utils.EnumStringValueTypeHandler" javaType="com.rrc.finance.order.core.unsubscribe.enums.UnsubscribeReasonDetailEnum"/>
</typeHandlers>
</configuration>最后就是配置启动项了,你写了xml不得让项目去自己扫描使用吗?下面以springBoot为例:
在MybatisConfiguration类的下的sqlSessionFactoryBean中加入:bean.setConfigLocation(resolver.getResource("classpath:mybatis-config.xml"));然后就OK了,可以完美的使用了。
在sqlSessionFactory里加入xml地址就行,可以和我一样在java类里写也可以直接在配置文件中写都行。
版权声明:本文为dianzijinglin原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。