问题描述
实体中的属性使用枚举和boolean会增加代码的可读性,但是实体和数据库的映射上不能很自然地支持,这样导致由于数据库的原因使得实体中属性使用基本类型来代替枚举和boolean。
实体中属性实例如下
private Integer status;// 0:草稿,1:合格 2:优秀 3:退回
private Byte open;//0;关闭 1:打开
在页面,java代码,和sql到处使用数字,使得代码可读性极差,代码越多,时间越长越没法维护。
<#if trainGroup.type==1>
<a href="javascript:" class="zi-lv" onclick="createAllGroup()" >教研组</a>
<#else>
<a href="javascript:" class="zi-lv" onclick="createAllCoop()" >协作组</a>
</#if>
param.setStatus(2); //优秀
或者使用常量(不能保证大家都使用常量,直接使用数字也没有错)param.setStatus(CONST.GOOD); //优秀
select ....
from T_DT_TRAIN_GROUP t .....m.STATUS = 2
使用枚举后的代码如下
<#if trainGroup.type=='JIAOYAN'>
<a href="javascript:" class="zi-lv" onclick="createAllGroup()" >教研组</a>
<#else>
<a href="javascript:" class="zi-lv" onclick="createAllCoop()" >协作组</a>
</#if>
param.setStatus(Status.GOOD);//只能使用枚举,否则编译通不过
select ....
from T_DT_TRAIN_GROUP t .....m.STATUS =${@cn.com.Status@GOOD.getValue()}
解决办法
在mybatis中实体属性与表字段之间的映射使用TypeHandler机制,mybatis本身提供了两种枚举类型的转换 EnumTypeHandler和EnumOrdinalTypeHandler。
EnumTypeHandler:将枚举值转化成字符串,字符串取枚举值的名称,使用枚举的.name()方法。EnumTypeHandler已经被内置了,只需要将实体属性改成枚举即可,不需要做任何TypeHandler配置,下面是mybatis获得TypeHandler的源码,如果没有匹配上任何TypeHandler,并且属性是枚举类型就使用EnumTypeHandler。
private <T> TypeHandler<T> getTypeHandler(Type type, JdbcType jdbcType) {
Map<JdbcType, TypeHandler<?>> jdbcHandlerMap = TYPE_HANDLER_MAP.get(type);
TypeHandler<?> handler = null;
if (jdbcHandlerMap != null) {
handler = jdbcHandlerMap.get(jdbcType);
if (handler == null) {
handler = jdbcHandlerMap.get(null);
}
}
if (handler == null && type != null && type instanceof Class && Enum.class.isAssignableFrom((Class<?>) type)) {
handler = new EnumTypeHandler((Class<?>) type);
}
@SuppressWarnings("unchecked")
// type drives generics here
TypeHandler<T> returned = (TypeHandler<T>) handler;
return returned;
}
这种方式最简洁,不需要做任何配置,但是要求表字段中存储的是枚举的名称。
EnumOrdinalTypeHandler:将枚举值转换数字,使用的是枚举的.ordinal()方法。如果要使用这种方式必须给每一个枚举类配置一次EnumOrdinalTypeHandler,如下给两个枚举配置同一个
EnumOrdinalTypeHandler,没有配置的枚举会走默认的EnumTypeHandler。
<typeHandlers>
<!-- <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
javaType="cn.com.teacher.cistus.dt.entity.TestMenu" /> -->
<typeHandler
handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
javaType="cn.com.teacher.cistus.dt.enums.EnumTrainGroupType" />
<typeHandler
handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
javaType="cn.com.teacher.cistus.dt.enums.EnumPortalConfigType" />
</typeHandlers>
sql mapper中如何使用枚举
public class TrainGroup extends AbstractEntity
private EnumTrainGroupType type;//0教研组 1协作组
映射和查询条件中不用任何特殊处理即可使用枚举。
<resultMap id="BaseResultMap" type="cn.com.teacher.cistus.dt.entity.TrainGroup" >
<result column="TYPE" property="type" jdbcType="INTEGER" />
。。。
<if test="type != null" >
TYPE = #{type,jdbcType=INTEGER},
</if>
sql中使用枚举常量
如下示例直接在sql中使用枚举,这样提高了代码的可读性,并且枚举值写错了会报错提示的。type=${@cn.com.teacher.cistus.
dt.enums.EnumTrainGroupType@JIAOYAN.ordinal()}
枚举常量的获取使用了ongl表达式的功能,${@cn.co。。GroupType@JIAOYAN.ordinal()}是原生的ongl执行静态代码的写法。
枚举值按指定值映射
mybatis本身只提供了上面两种枚举映射方式,如果想映射自定义的值,比如
JIAOYAN(10,"教研组"),XIEZUO(20,"协作组");映射成 10 ,20.
public class EnumValueTypeHandler <E extends Enum & IDBEnum> extends BaseTypeHandler<E>{
private Class<E> type;
// private final E[] enums;
public EnumValueTypeHandler(Class<E> type) {
this.type = type;
E[] enums = type.getEnumConstants();
if (enums == null) {
throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
ps.setInt(i, parameter.getValue());
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
int i = rs.getInt(columnName);
if (rs.wasNull()) {
return null;
} else {
try {
return DBEnumUtils.getEnumInstance(type,i);
} catch (Exception ex) {
throw new IllegalArgumentException("Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex);
}
}
}
@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
int i = rs.getInt(columnIndex);
if (rs.wasNull()) {
return null;
} else {
try {
return DBEnumUtils.getEnumInstance(type,i);
} catch (Exception ex) {
throw new IllegalArgumentException("Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex);
}
}
}
@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
int i = cs.getInt(columnIndex);
if (cs.wasNull()) {
return null;
} else {
try {
return DBEnumUtils.getEnumInstance(type,i);
} catch (Exception ex) {
throw new IllegalArgumentException("Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex);
}
}
}
}
public enum EnumTrainGroupType implements IDBEnum{
JIAOYAN(10,"教研组"),XIEZUO(20,"协作组");
private int value;
private String name;
EnumTrainGroupType(int value,String name){
this.value=value;
this.name=name;
}
@Override
public int getValue() {
return value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setValue(int value) {
this.value = value;
}
}
相关推荐
本项目为mybatis实战二之枚举类型,里面有简单的demo,适合初学者下载运行,能对mybatis的typehandler有一个初始的认识和运用
1. boot+mybatis的demo项目 2.mybatis中枚举转换器问题等 3.前后端分离项目统一返回json格式 4.boot集成quraz框架实现定时任务
MyBatis 枚举全面使用指南 抓下来打包成了HTML文件, 方便离线观看
枚举类型是我们在开发中经常遇到的一个类型,最近在学习MyBatis,但是发现网上没有详细介绍MyBatis如何使用枚举的相关文章,索性就自己写一篇,下面这篇文章主要给大家介绍了关于在MyBatis中如何优雅的使用枚举的...
在使用mybatis的时候经常会遇到枚举类型的转换,下面这篇文章主要给大家介绍了关于mybatis中实现枚举自动转换的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们...
MyBatis的学习代码MyBatis的学习代码MyBatis的学习代码MyBatis的学习代码MyBatis的学习代码MyBatis的学习代码MyBatis的学习代码MyBatis的学习代码MyBatis的学习代码MyBatis的学习代码MyBatis的学习代码MyBatis的学习...
SpringMVC+Mybatis,CRM系统教程和源代码(SSM项目)SpringMVC+Mybatis,CRM系统教程和源代码(SSM项目)
mybatis代码生成插件,配置下就可以生成任意表的mybatis配置了
Mybatis MySql 代码生成工具,内有jar包,配置说明。自动生成 model xml 。
mybatis-plus代码生成器模版代码
mybatis简单使用mybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单...
MyBatis代码生成工具,内含mybatis-generator-core-1.4.0-SNAPSHOT.jar,mysql-connector-java-5.1.47.jar
springmvc+mybatis 和一个简单的freemarker代码生成工具
MyBatis学习代码: mybatis实战教程mybatis in action之一开发环境搭建 mybatis实战教程mybatis in ...mybatis实战教程mybatis in action之九mybatis 代码生成工具的使用 mybatis SqlSessionDaoSupport的使用附代码下载
mybatis-plus最新代码生成器项目源码 :mybatis-plus-generator.zip mybatis-plus最新代码生成器项目源码 :mybatis-plus-generator.zip mybatis-plus最新代码生成器项目源码 :mybatis-plus-generator.zip ...
使用Mybatis Generator自动生成Mybatis相关代码
主类在GeneratorMain,只要指定几个关键点,输出路径,输入表名,上级包名,就能生成代码后,直接复制到工程中,生成类中结构清晰,注释完整。 /** * 生成演示 */ public static void main(String[] args) { ...
可自动生成代码 oracle mysql都可以使用 告别重复劳动,提高代码效率。
oracle 结合 mybatis-plus 逆向工程生成代码
MyBatis-3.4.1架包和源代码MyBatis-3.4.1架包和源代码MyBatis-3.4.1架包和源代码