类型处理器(TypeHandler)

无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成 Java 类型。

通过类型处理器(TypeHandler),可以实现javaBean以某种方式存入数据库中,抑或是从数据库取出的数据如何映射为javaBean。

通过继承BaseTypeHandler类,我们可以定制这个类型处理器,已实现枚举类或是一个javaBean的存取和写入。

内置的枚举处理器

mybatis内置了两个枚举类型处理器,EnumTypeHandler和EnumOrdinalTypeHandler,这两个类型都不好用,一般也是我们自己实现枚举的类型处理器。

EnumTypeHandler存入数据库的是枚举的name,EnumOrdinalTypeHandler存入数据库的是枚举的位置。例如下方的枚举,当我们有一个枚举值是EStatus.init时,这时我们使用mybatis的EnumTypeHandler存入数据库的是"init"字符串;而EnumOrdinalTypeHandler存入的是3,因为init是第四个值,第一个值disable的index是0。

public enum EStatus {

disable("0"), enable("1"), deleted("2"),

init("10"), start("11"), wait("12"), end("13");

}

EnumTypeHandler源码

public class EnumTypeHandler> extends BaseTypeHandler {

private final Class type;

//采用父类的构造方法,会获取到注解MappedTypes中的value,作为type

public EnumTypeHandler(Class type) {

if (type == null) {

throw new IllegalArgumentException("Type argument cannot be null");

} else {

this.type = type;

}

}

//写入数据库时调用

public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {

if (jdbcType == null) {

ps.setString(i, parameter.name());

} else {

ps.setObject(i, parameter.name(), jdbcType.TYPE_CODE);

}

}

//以下三个方法是在存入时候调用,一个是根据列名获取值,一个是根据列索引位置获取值,最后一个是存储过程。

public E getNullableResult(ResultSet rs, String columnName) throws SQLException {

String s = rs.getString(columnName);

return s == null ? null : Enum.valueOf(this.type, s);

}

public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {

String s = rs.getString(columnIndex);

return s == null ? null : Enum.valueOf(this.type, s);

}

public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {

String s = cs.getString(columnIndex);

return s == null ? null : Enum.valueOf(this.type, s);

}

}

自定义枚举类处理

1、实现BaseTypeHandler接口,重写方法

public class GenderHandler extends BaseTypeHandler {

@Override

public void setNonNullParameter(PreparedStatement preparedStatement, int i, Gender gender, JdbcType jdbcType) throws SQLException {

preparedStatement.setString(i, gender.getCode());

}

@Override

public Gender getNullableResult(ResultSet resultSet, String s) throws SQLException {

return Gender.getGender(resultSet.getString(s));

}

@Override

public Gender getNullableResult(ResultSet resultSet, int i) throws SQLException {

return Gender.getGender(resultSet.getString(i));

}

@Override

public Gender getNullableResult(CallableStatement callableStatement, int i) throws SQLException {

return Gender.getGender(callableStatement.getString(i));

}

}

2、在application.yml中加入配置,扫描handler组件

mybatis:

# 配置mybatis的resultType别名,默认是别名为小写

type-aliases-package: com.lexiaoyao.mybatisdemo.domain

# 配置扫描的xml文件位置

mapper-locations: classpath:mybatis/mapper/*.xml

# mybatis详细配置文件

config-location: classpath:mybatis/mybatis-config.xml

# 扫描handler组件

type-handlers-package: com.lexiaoyao.mybatisdemo.handler

通用枚举处理器

note 这里将mysql数据库里字段定义为char(1)

1、定义枚举类的接口,统一格式

public interface BaseEnum, T> {

T getCode();//code为存入数据库的值

String getInfo();//info为实际意义

}

2、定义枚举类

public enum Gender implements BaseEnum {

Male("1", "男"),

Female("0", "女"),

Unknown("3", "保密");

private String code;

private String info;

Gender(String code, String info) {

this.code = code;

this.info = info;

}

public static Gender getGender(String code) {

return Arrays.stream(Gender.values()).filter(i -> i.getCode().equals(code)).findAny().orElse(null);

}

public String getCode() {

return code;

}

public void setCode(String code) {

this.code = code;

}

public String getInfo() {

return info;

}

public void setInfo(String info) {

this.info = info;

}

}

3、编写统一的枚举映射handler

public class NormalEnumHandler extends BaseTypeHandler {

private Class enumType;

private E[] enums;

public NormalEnumHandler(Class 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.getSimpleName()

+ " does not represent an enum type.");

}

public NormalEnumHandler() {

}

@Override

public void setNonNullParameter(PreparedStatement preparedStatement, int i, E e, JdbcType jdbcType) throws SQLException {

if (jdbcType == null) {

preparedStatement.setString(i, (String) e.getCode());

} else {

preparedStatement.setObject(i, e.getCode(), jdbcType.TYPE_CODE);

}

}

@Override

public E getNullableResult(ResultSet resultSet, String s) throws SQLException {

return resultSet.wasNull() ? null : locateEnumStatus(resultSet.getString(s));

}

@Override

public E getNullableResult(ResultSet resultSet, int i) throws SQLException {

return resultSet.wasNull() ? null : locateEnumStatus(resultSet.getString(i));

}

@Override

public E getNullableResult(CallableStatement callableStatement, int i) throws SQLException {

return callableStatement.wasNull() ? null : locateEnumStatus(callableStatement.getString(i));

}

private E locateEnumStatus(String value) {

return Arrays.stream(enums)

.filter(i -> i.getCode().equals(value))

.findAny()

.orElseThrow(() -> new IllegalArgumentException("未知的枚举类型:" + value + ",请核对" + enumType.getSimpleName()));

}

}

4、相应的扫描包下只需写一个Handler,并继承NormalEnumHandler

@MappedTypes(value = {Gender.class})

public class NormalHandler extends NormalEnumHandler {

public NormalHandler(Class type) {

super(type);

}

}

要新加入枚举时候,只需要在MappedTypes的数据里添加一个即可。

5、配置扫描包

mybatis:

# 配置mybatis的resultType别名,默认是别名为小写

type-aliases-package: com.lexiaoyao.mybatisdemo.domain

# 配置扫描的xml文件位置

mapper-locations: classpath:mybatis/mapper/*.xml

# mybatis详细配置文件

config-location: classpath:mybatis/mybatis-config.xml

# 扫描handler组件

type-handlers-package: com.lexiaoyao.mybatisdemo.handler

Git

mysql enum mybatis_Mybatis 枚举类处理相关推荐

  1. 枚举类——概述、常用方法、自定义枚举类、Enum创建枚举类

    一.枚举类的概述 1.枚举类的理解:类的对象只有有限个,确定的.我们称此类为枚举类 2.当需要定义一组常量时,强烈建议使用枚举类 3.如果枚举类中只一个对象,则可以作为单例模式的实现方式. 二.枚举类 ...

  2. 通过enum实现枚举类

    枚举 发现自己定义一个枚举类,比较麻烦,所以,java就提供了枚举类供我们使用. 格式是:只有枚举项的枚举类 public enum 枚举类名 {             枚举项1,枚举项2,枚举项3 ...

  3. 重新认识java(十) ---- Enum(枚举类)

    有的人说,不推荐使用枚举.有的人说,枚举很好用.究竟怎么使用,如何使用,仁者见仁智者见智.总之,先学会再说~ 为什么要引入枚举类 一个小案例 你写了一个小程序,不过好久不用了,突然有一天,你想使用一下 ...

  4. C++ enum class枚举类

    目录 一.定义 二.使用 1.用法 2.优点 三.注意事项 1.初始化和赋值 2.类型转换 一.定义 枚举类型:是用户定义的若干枚举常量的集合,属于用户自定义的数据类型. C++枚举包含两种:限定作用 ...

  5. C# Idioms: Enum还是Enum Class(枚举类)

    原文排版格式:http://www.marshine.com) reversion:2004/5/28 修改说明:感谢Ninputer提到的CLS兼容问题,同时修改了原来版本没有提及的Equals改写 ...

  6. 枚举类 enum,结构体类 struct

    1.枚举类型的值,直观易于理解,见词知意. 格式: enum 枚举类名:值类型{值1,值2,值n} 每个值默认(省略":值类型")以int型数据存储,从0开始. 使用格式:枚举类名 ...

  7. Java中的枚举类是什么?enum关键字怎么使用?

    枚举类 文章目录 枚举类 枚举类的使用:入门 自定义枚举类 方法一:自定义枚举类 方式二: enum 关键字定义枚举类(主要用该方式) Enum类的主要方法 使用enum关键字定义的枚举类实现接口 主 ...

  8. java 枚举类型enum ppt,关于JAVA枚举类使用的异常

    当前位置:我的异常网» J2SE » 关于JAVA枚举类使用的异常 关于JAVA枚举类使用的异常 www.myexceptions.net  网友分享于:2013-01-24  浏览:5次 关于JAV ...

  9. java 枚举的继承_java中枚举类可以被继承吗?

    java 枚举类 java中,使用关键字enum来定义枚举类,枚举类是一个特殊的类,大部分功能和普通类是一样的,区别为: ● 枚举类继承了java.lang.Enum类,而不是默认的Object类.而 ...

最新文章

  1. centos7 yum 错误 This system is not registered with an entitlement server
  2. iso linux 内核版本号_Linux查看 iso 版本信息
  3. 1098 Insertion or Heap Sort (25 分)【难度: 中 / 插入排序 堆排序 堆排序不会未完成】
  4. SAP评估级别 Valuation Area
  5. maven学习笔记之IDEA+Maven+Jetty运行一个简单的web项目
  6. 现代交换技术学习笔记001
  7. python3虚拟环境使用教程_python虚拟环境完美部署教程
  8. Geometric Shapes - POJ 3449(多边形相交)
  9. Python数模笔记-模拟退火算法(2)约束条件的处理
  10. fork-join详解(2)
  11. ubuntu-常用命令汇总
  12. 机器学习——数据的预处理(总结大全)
  13. 小程序--模板的使用 说明--详细版的
  14. 23篇大数据系列(三)sql基础知识(史上最全,建议收藏)
  15. 脉冲电磁阀工作原理图(给到爱学习的你)(转)
  16. 龙芯LoongArch电脑上用dh-make打包deb包
  17. 微信小程序 开发者工具和真机调试都能正常请求访问,线上不能登录请求问题
  18. 苹果计算机重装系统步骤,苹果mac系统重装_苹果电脑Mac系统重装方法
  19. Linux下安装调试MQTT Mosquitto
  20. Java录制网页_Java 录制语音的实现代码

热门文章

  1. 在NodeJS中操作文件常见的API
  2. pycharm 远程环境开发调试
  3. 从信息熵到Codec
  4. ashx是什么文件,如何创建[转]
  5. 个人信息泄露致电信诈骗猖獗 专家:治理亟须完善立法
  6. 第八章教材内容总结:异常控制流
  7. 使用autoconf完成编译配置
  8. 【Python学习笔记】注释,代码块,多行输出,忽略转义符的输出
  9. serv-u的语言界面的切换(汉英切换)
  10. 修改exe图标,加入版本号