在数据模型、接口参数等场景部分属性参数为一些常量值,比如性别:男、女。若是定义成int或String类型,于是类型本身的范围太宽,要求使用者需要了解底层的业务方可知如何传值,那整体来看增加沟通成本,对接效率也低。面对此等业务,使用枚举简便许多。枚举enum像个固定常量类,也像一个数组。

public enum Sex {
Male(1,"男"),
FeMale(2,"女"),
;
private int index;
private String description;
Sex(int index, String description){
this.index = index;
this.description = description;
}
public int getIndex() {
return index;
}
public String getDescription() {
return description;
}
}

定义枚举,存储到数据库为int。这里就需要使用上mybatis的类型处理器功能。mybatis定义了接口TypeHandler用于数据转换。

public interface TypeHandler<T> {
void setParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException;
T getResult(ResultSet var1, String var2) throws SQLException;
T getResult(ResultSet var1, int var2) throws SQLException;
T getResult(CallableStatement var1, int var2) throws SQLException;
}

mybatis内置了许多类型处理器:IntegerTypeHandlerBigDecimalTypeHandlerEnumTypeHandlerEnumOrdinalTypeHandler

EnumTypeHandler 数据库字符串类型,用以存储枚举的名称(Male, FeMale);

EnumOrdinalTypeHandler 数据库为数值类型,存储枚举的序数值

从 3.4.5 开始,MyBatis 默认支持 JSR-310(日期和时间 API):LocalDateTypeHandlerLocalDateTimeTypeHandler等。

你可以重写或自定义实现所需的类型转换器,实现org.apache.ibatis.type.TypeHandler 接口 或者继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler。

mybatis默认的枚举实现类,不能把index存入数据库中,因此需自定义实现器。

在项目定义的枚举不止一个,若是单个枚举转换,代码成本太高,维护扩展也困难。那有没有办法写一个通用的转换器呢?

可以的。

一、为了区分那些需要转换的枚举,提取些共同属性,定义成接口,需转皆实现此接口即可。

public interface BaseEnum{
int getIndex();
String getDescription();
}
public enum Sex implements BaseEnum{
Male(1,"男"),
FeMale(2,"女"),
;
private int index;
private String description;
Sex(int index, String description){
this.index = index;
this.description = description;
}
public int getIndex() {
return index;
}
public String getDescription() {
return description;
}
}

二、自定义类型转换器AutoGenericEnumTypeHandler,继承BaseTypeHandler。因为是通用类型,所以使用到java 泛型的参数

public class AutoGenericEnumTypeHandler<E extends BaseEnum> extends BaseTypeHandler<E> {

    private Class<E> enumType;
private E[] enums; public AutoGenericEnumTypeHandler(){} public AutoGenericEnumTypeHandler(Class<E> type){
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.enumType = type;
this.enums = type.getEnumConstants();
if (this.enums == null) {
throw new IllegalArgumentException(type.getName() + " does not represent an enum type.");
}
} private E loadEnum(int index) {
for (E e : enums) {
if (e.getIndex() == index) {
return e;
}
}
throw new IllegalArgumentException(enumType.getName() + " unknown enumerated type index:" + index);
} @Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
ps.setInt(i, parameter.getIndex());
} @Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
if(rs.getObject(columnName) == null){
return null;
}
int index = rs.getInt(columnName);
return loadEnum(index);
} @Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
if(rs.getObject(columnIndex) == null){
return null;
}
int index = rs.getInt(columnIndex);
return loadEnum(index);
} @Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
if(cs.getObject(columnIndex) == null){
return null;
}
int index = cs.getInt(columnIndex);
return loadEnum(index);
}
}

三、配置使用。3.4.5版本后提供配置默认枚举转换器即,不用侵入写代码(侵入写法源代码下载路径:https://gitee.com/zss_376987715/mybatis-dao)

spring boot的配置:mybatis.configuration.default-enum-type-handler=com.XXX.typehandler.AutoGenericEnumTypeHandler

spring项目通过mybatis-config.xml配置文件:

<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="defaultEnumTypeHandler" value="com.XXX.typehandler.AutoGenericEnumTypeHandler"/>
</settings>
</configuration>

到此已经实现转换。

如果正在参照(https://www.cnblogs.com/song27/p/10977241.html)学习多数据源。需要对代码有点改动。

在创建SqlSessionFactory 时,添加MybatisProperties mybatisProperties参数,重新加载configuration。不然spring boot的application.properties配置不会生效。因为未加载进去。

@Bean
public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource, MybatisProperties mybatisProperties) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setConfiguration(mybatisProperties.getConfiguration());
return sessionFactory.getObject();
}

mybatis类型转换器 - 自定义全局转换enum的更多相关文章

  1. Struts2之自定义局部类型转换器、全局类型转换器

    Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器  如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用 ...

  2. (三)Mybatis类型转换器,接口传参类型,一对一,一对多查询resultMap配置

    Mybatis类型转换器 首先明白什么时候用到它,当数据库的字段类型和java字段类型无法默认匹配时候进行转换,比如现在数据库类型是INTEGER,而java当中类型是Boolean,true表示1, ...

  3. Struts2第五篇【类型转换器、全局、局部类型转换器】

    前言 上篇博文已经讲解了,Struts2为我们实现了数据自动封装-由上篇的例子我们可以看出,表单提交过去的数据全都是String类型的,但是经过Struts自动封装,就改成是JavaBean对应成员变 ...

  4. springmvc 类型转换器 自定义类型转换器

    自定义类型转换器的步骤: 1.定义类型转换器 2.类型转换器的注册(在springmvc配置文件处理) 来解决多种日期格式的问题: springmvc 类型转换器 表单数据填错后返回表单页面(接上面的 ...

  5. Struts2之自定义类型转换器

    Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用d ...

  6. struts2自定义类型转换器

    首先,何为struts2的类型转换器? 类型转换器的作用是将请求中的字符串或字符串数组参数与action中的对象进行相互转换. 一.大部分时候,使用struts2提供的类型转换器以及OGNL类型转换机 ...

  7. springmvc——自定义类型转换器

    一.什么是springmvc类型转换器? 在我们的ssm框架中,前端传递过来的参数都是字符串,在controller层接收参数的时候springmvc能够帮我们将大部分字符串类型的参数自动转换为我们指 ...

  8. 8.Struts2类型转换器

    类型转换器1.引入在Struts2中,请求参数类型不仅可以是String,还可以是其它类型.如,定义一个请求参数birthday为Date类型,给其赋值为1949-10-1,则birthday接收到的 ...

  9. Struts2:类型转换器

    常规的String,int能自动转换,但是,有些类型不是这么简单,比如输入字符串,但需要Date.自定义类型,因此需要自定义类型转换类型转换器分全局和局部按惯例,局部的优先级高于全局 需求: 1.输入 ...

随机推荐

  1. Parentheses Balance (括号平衡)---栈

    题目链接:https://vjudge.net/contest/171027#problem/E Yes的输出条件: 1. 空字符串 2.形如()[]; 3.形如([])或者[()] 分析: 1.设置 ...

  2. 《和莎莫的 500 天》中为什么 Summer 最终没有和 Tom 在一起?

    好的电影总是需要仔细赏味几次,每次也都会有不同的收获.就像我钟爱的[500 days of summer]. 彪悍的大胡子导演MarcWebb实在是太有趣,把自己的亲身经历搬上大荧幕,因为" ...

  3. 硬件小白学习之路(1)稳压芯片LM431

    图稳压芯片LM431简介 偶然的机会接触到LM431这个芯片,周末晚上打发无聊的时光,查资料进行剖析. LM431的Symbol Diagram和Functional Diagram如图1所示,下面分 ...

  4. 聊一聊关于MySQL的count(*)

    0.背景 自从大家对于MySQL数据库的稳定性有了更高的追求后,经常有小伙伴有这样的疑问,对于count(*)这样的操作,有没有正确的姿势,或者有没有可以优化的地方? 但答案比较残酷,如果已经使用了正 ...

  5. 7-35 jmu-python-求三角形面积及周长 (10 分)

    输入的三角形的三条边a.b.c,计算并输出面积和周长.假设输入三角形三边是合法整形数据. 三角形面积计算公式:  ,其中s=(a+b+c)/2. import math #导入math库 math.s ...

  6. html+css+js+Hbuilder开发一款安卓APP,根本不用学Android开发!

    我们知道,要做一款安卓APP,咱们得先学安卓开发语言,例如java,前端后端.那么没有这些开发语言基础,咱们怎么做呢?其实现在有比较好的开发方案就是做webAPP,咱们可以用web前端知识构建安卓客户 ...

  7. 机器学习实战:意大利Covid-19病毒感染数学模型及预测

    作者:Gianluca Malato deephub翻译组:刘欣然 当今世界正在与一个新的敌人作斗争,那就是Covid-19病毒. 该病毒自首次在中国出现以来,在世界范围内迅速传播.不幸的是,意大利的 ...

  8. 使用flask-dropzone 上传图片文件

    引用  http://greyli.com/flask-dropzone/ 现在需要上传图片文件的页面使用jijin2渲染,由于是使用flask-dropzone的,所以我们使用dropzone的cs ...

  9. 《即时消息技术剖析与实战》学习笔记12——IM系统如何提升图片、音视频消息发送、浏览的体验

    IM系统如何提升用户发送.浏览图片和音视频消息的体验呢?一是保证图片.音视频消息发送得又快又稳,二是保证用户浏览播放图片.音视频消息时流畅不卡顿. 一.提升用户发送图片.音视频的体验 1. 多上传接入 ...

  10. 【Spring Data 系列学习】Spring Data JPA @Query 注解查询

    [Spring Data 系列学习]Spring Data JPA @Query 注解查询 前面的章节讲述了 Spring Data Jpa 通过声明式对数据库进行操作,上手速度快简单易操作.但同时 ...