https://blog.csdn.net/fighterandknight/article/details/51520595

https://blog.csdn.net/fighterandknight/article/details/51599116

https://blog.csdn.net/fighterandknight/article/details/51600997

版权声明:本文为Fighter168原创文章,未经允许不得转载。 https://blog.csdn.net/fighterandknight/article/details/51520595
前言
         在上一篇博客,mybatis枚举自动转换实现,已经介绍自动转换的实现步骤,并通过例子告诉大家如何实现枚举的自动转换了。 那么在博客的最后想到,定义一个万能的枚举转换处理器,具体怎么实现呢,相信大神们也应该有思路了,使用泛型实现,没错,就是使用泛型实现,具体请看下面例子。

mybatis万能枚举转换处理器
定义枚举接口
为什么要定义枚举的接口呢,定义接口的好处,其实主要目的是为了在万能枚举转换器中方便泛型的使用,而且还可以规范枚举类的实现。
package net.itaem.less;

/**
* @author: Fighter168
*/
public interface BaseEnum<E extends Enum<?>, T> {
public T getValue();
public String getDisplayName();
}

实现枚举接口,定义枚举
实现BaseEnum接口,定义PersonType枚举
package net.itaem.less;

import java.util.HashMap;
import java.util.Map;

/**
* @author: Fighter168
*/
public enum PersonType implements BaseEnum<PersonType, String>{
student("1","学生"),
teacher("2","教师");

private String value;
private String displayName;

static Map<String,PersonType> enumMap=new HashMap<String, PersonType>();
static{
for(PersonType type:PersonType.values()){
enumMap.put(type.getValue(), type);
}
}

private PersonType(String value,String displayName) {
this.value=value;
this.displayName=displayName;
}

public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}

public static PersonType getEnum(String value) {
return enumMap.get(value);
}
}

定义万能枚举转换处理器
package net.itaem.handler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import net.itaem.less.BaseEnum;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

/**
* @author: Fighter168
*/
public final class UniversalEnumHandler<E extends BaseEnum> extends BaseTypeHandler<E> {

private Class<E> type;
private E [] enums;

/**
* 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
* @param type 配置文件中设置的转换类
*/
public UniversalEnumHandler(Class<E> 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, E parameter,
JdbcType jdbcType) throws SQLException {
//BaseTypeHandler已经帮我们做了parameter的null判断
ps.setObject(i,(String)parameter.getValue(), jdbcType.TYPE_CODE);
}

@Override
public E getNullableResult(ResultSet rs, String columnName)
throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型
String i = rs.getString(columnName);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的value值,定位PersonType子类
return locateEnumStatus(i);
}
}

@Override
public E getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型
String i = rs.getString(columnIndex);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的value值,定位PersonType子类
return locateEnumStatus(i);
}
}

@Override
public E getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型
String i = cs.getString(columnIndex);
if (cs.wasNull()) {
return null;
} else {
// 根据数据库中的value值,定位PersonType子类
return locateEnumStatus(i);
}
}

/**
* 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷
* @param value 数据库中存储的自定义value属性
* @return value对应的枚举类
*/
private E locateEnumStatus(String value) {
for(E e : enums) {
if(e.getValue().equals(value)) {
return e;
}
}
throw new IllegalArgumentException("未知的枚举类型:" + value + ",请核对" + type.getSimpleName());
}
}

测试
           接下来,我们就修改原来的例子(上一篇博客的例子:mybatis枚举自动转换实现),只需修改typeHandler,修改成
<typeHandler handler="net.itaem.handler.UniversalHandler"
javaType="net.itaem.less.PersonType" jdbcType="CHAR"/>
然后我们再次运行测试用例,会发现,我们的查询得到的结果还是一样,这样,我们就不需要为每一个枚举创建一个Handler去自动转换数据库中的枚举了。

自动扫描枚举注册想法
             做到这里,或许我们又想了,要是我们一个项目特别大,有几十个甚至是上百个枚举呢,那怎么办,难道我要一个个在typeHandler里面去加,加一百几十行?!个人觉得非常麻烦,影响我们的开发速度,so,能不能实现我们想要的像扫描下枚举的所在的包目录就可以注册的枚举做自动转换呢?具体怎么实现?下篇博客我会教大家如何实现。

---------------------
作者:Fighter168
来源:CSDN
原文:https://blog.csdn.net/fighterandknight/article/details/51520595
版权声明:本文为博主原创文章,转载请附上博文链接!

mybatis枚举自动转换(通用转换处理器实现)的更多相关文章

  1. Mybatis枚举转换

    自定义mybatis枚举转换,原理是如果用户没有定义自己的枚举转换工具,mybatis在解析枚举类时会自动获取mybatis的BaseTypeHandler,来转换枚举类,我们只需要重写这个枚举转换器 ...

  2. mybatis类型转换器 - 自定义全局转换enum

    在数据模型.接口参数等场景部分属性参数为一些常量值,比如性别:男.女.若是定义成int或String类型,于是类型本身的范围太宽,要求使用者需要了解底层的业务方可知如何传值,那整体来看增加沟通成本,对 ...

  3. Mybatis 枚举类处理

    目录 类型处理器(TypeHandler) 内置的枚举处理器 EnumTypeHandler源码 自定义枚举类处理 通用枚举处理器 Git 类型处理器(TypeHandler) 无论是 MyBatis ...

  4. SpringBoot 添加mybatis generator 自动生成代码插件

    自动生成数据层代码,提高开发效率 1.pom添加插件,并指定配置文件路径 <!-- mybatis generator 自动生成代码插件 --> <plugin> <gr ...

  5. idea中mybatis generator自动生成代码配置 数据库是sqlserver

    好长时间没有写博客了,最近公司要用java语言,开始学习java,属于初学者,今天主要记录一下mybatis generator自动生成代码,首先在如下图的目录中新建两个文件,如下图 generato ...

  6. mybatis 枚举typeHandler

    枚举typeHandler 在绝大多数情况下,typeHandler因为枚举而使用,MyBatis已经定义了两个类作为枚举类型的支持,这两个类分别是: •EnumOrdinalTypeHandler. ...

  7. Springboot 系列(十一)使用 Mybatis(自动生成插件) 访问数据库

    1. Springboot mybatis 介绍 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数获取 ...

  8. MyBatis代码自动生成(利用命令)

    这几天在学习springmvc,需要用到mybatis,所以研究了一下mybatis自动代码生成,当然也可以手动敲,但是那样效率非常的慢,并且出错率也是很高的,利用MyBatis生成器自动生成实体类. ...

  9. SSM框架——使用MyBatis Generator自动创建代码

    版权声明:本文为博主原创文章,未经博主允许不得转载. 这两天需要用到MyBatis的代码自动生成的功能,由于MyBatis属于一种半自动的ORM框架,所以主要的工作就是配置Mapping映射文件,但是 ...

随机推荐

  1. hdu 1011 Starship Troopers 树形背包dp

    Starship Troopers Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  2. Java中的long与double的区别

    1.long与double在java中本身都是用64位存储的,但是他们的存储方式不同,导致double可储存的范围比long大很多 2.long可以准确存储19位数字,而double只能准备存储16位 ...

  3. 三: 爬虫之selenium模块

    一 selenium模块 什么是selenium?selenium是Python的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作. selenium最初是一个自动化测试工具, ...

  4. 面试题中关于String的常见操作

    题目1: 将用户输入的一段话,每个单词的首字母大写, 每个单词之间的空格调整为只有一个,遇到数字,将数字与后一个单词用下划线 "_" 进行连接 题目2:将 i @@ am @@@ ...

  5. Linux系统vi或者vim编辑器中如何显示行号

    设置行号很简单 我们要到vi或者vim编辑器的命令模式下,输入set number :set number 按下回车就显示行号了 那么怎么关闭行号呢? 很简单,我们只要再到vi或者vim编辑器的命令模 ...

  6. idea中svn的使用教程

    引言:以下是idea集成小乌龟后的svn使用教程,一张图足以说明问题,后续如果遇到了比较复杂一点的问题再来补充. 参考文档:https://blog.csdn.net/liuhailiuhai12/a ...

  7. [转][cesium]1.添加本地服务器

    转自:http://www.cnblogs.com/fuckgiser/p/5633748.html 此系列cesium总教程:  https://www.cnblogs.com/fuckgiser/ ...

  8. [原][osg][osgearth]倾斜摄影1.介绍

    总体介绍: 倾斜摄影就是将拍好的数据,三角网格化再附上贴图. 目前流行处理软件: Street Factory.PIX4DMapper.smart3D 后期开发平台:超图 Skyline smart3 ...

  9. es6 Set 结合 Array.from 用法

    var arr=[1,2,3,2,3,4,5]; var set=new Set(arr) var arr1=Array.from(set) 重复数组  -  Set 化 (去重) - 转回数组 上述 ...

  10. 生成pyd文件时提示“Unable to find vcvarsall.bat”的问题

    本文内容 Unable to find vcvarsall.bat的问题描述 问题分析 总结 一.问题描述 我们在windows下通过pip安装一些外部Python 模块(比如,pycrypto)时通 ...