mybatis枚举类型转换器详解

tk.mybatis 2.1.15 如何将枚举类型在类中进行自动转换 tk.mybatis 如何自定义枚举类型转换 阅读详情

前言

刚入手spring-boot还不太熟练,先弄了个空的框架,然后写了个简单的用户查询,没啥挑战性。然后想起来之前一直对枚举不太了解,而用户的性别正好可以用枚举类型来表示(male, female)。于是就开始了自己的挖坑之旅。 本文主要分为三个部分:

  • 背景
  • mybatis自带枚举类型转换器
  • 自定义枚举类型转换器

背景

假设目前有一张user_info表,我们需要将用户的性别存到数据库里,我们都知道“性别”只可能有两种取值:male或者famale,一般不会出现第三种,这就是我们所知道的枚举类型。可是将male和famale存到数据库里显然不太优雅,也会浪费大量数据库存储空间。我们可以约定0/1分别表示male和female,这样就可以用一个bit就存储原本需要多个字节存储的数据。

mybatis自带枚举类型转换器

MyBatis内置了两个枚举转换器分别是:org.apache.ibatis.type.EnumTypeHandler和org.apache.ibatis.type.EnumOrdinalTypeHandler。
EnumTypeHandler
这是默认的枚举转换器,该转换器将枚举实例转换为实例名称的字符串,即将UserSex.MALE转换MALE。
EnumOrdinalTypeHandler
顾名思义这个转换器将枚举实例的ordinal属性作为取值,即UserSex.MALE转换为0,UserSex.FEMALE转换为1。
使用它的方式是在MyBatis配置文件中定义:

<typeHandlers>
    <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.example.entity.enums.ComputerState"/>
</typeHandlers>

看上去第二种好像已经满足我们的需求。可是,有时候我们需要存储更多的状态,如存储一个订单的状态,常见的有创建、交易中、支付成功、支付失败等等状态。我们定义这样一个枚举类:

public enum OrderStatusEnum {
    CREATE(0),
    PAYING(1),
    IN_PROGRESS(2),
    FAILED(3),
    REVERSED(4);

    private int value;

    OrderStatusEnum(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

定义的状态变多之后,数字表述的含义就没那么清晰明白,所以,我们需要对每个状态加上描述文字,可是这样就无法使用mybatis自带枚举类型转换器,需要我们自己设计一个枚举类型转换器,还好设计mybatis的大叔早就预料到了这种情况,所以特意留了相关的接口。

自定义枚举类型转换器

MyBatis提供了org.apache.ibatis.type.BaseTypeHandler类用于我们自己扩展类型转换器,上面的EnumTypeHandler和EnumOrdinalTypeHandler也都实现了这个接口。程序设计如下所示
枚举类

public enum OrderStatusEnum {
    CREATE(0, "创建"),
    PAYING(1, "支付中"),
    IN_PROGRESS(2, "支付成功"),
    FAILED(3, "支付失败"),
    REVERSED(4, "取消订单");

    private int value;
    private String desc;

    OrderStatusEnum(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }

    public int getValue() {
        return value;
    }

    public String getDesc() {
        return desc;
    }
}

实体类

public class OrderInfo {
    private int id;
    private OrderStatusEnum orderStatusEnum;
}

准备工作做的差不多了,是时候开始编写转换器了。
BaseTypeHandler 一共需要实现4个方法:

// 用于定义设置参数时,该如何把Java类型的参数转换为对应的数据库类型
void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType)

// 用于定义通过字段名称获取字段数据时,如何把数据库类型转换为对应的Java类型
T getNullableResult(ResultSet rs, String columnName)

// 用于定义通过字段索引获取字段数据时,如何把数据库类型转换为对应的Java类型
T getNullableResult(ResultSet rs, int columnIndex)

// 用定义调用存储过程后,如何把数据库类型转换为对应的Java类型
T getNullableResult(CallableStatement cs, int columnIndex)

具体实现如下

public class EnumOrderStatusHandler extends BaseTypeHandler<OrderStatusEnum> {

    /**
     * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
     * @param type 配置文件中设置的转换类
     */
    public EnumOrderStatusHandler(Class<OrderStatusEnum> type) {
        if (type == null)
            throw new IllegalArgumentException("Type argument cannot be null");
    }

    /**
     * 用于定义设置参数时,该如何把Java类型的参数转换为对应的数据库类型
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, OrderStatusEnum parameter, JdbcType jdbcType) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放int类型
        // ps.setString
        ps.setInt(i, parameter.getValue());
    }

    /**
     * 用于定义通过字段名称获取字段数据时,如何把数据库类型转换为对应的Java类型
     */
    @Override
    public OrderStatusEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放int类型
        // String i = rs.getString(columnName);
        int i = rs.getInt(columnName);
        if (rs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的值,定位Enum子类
            return locateEnum(i);
        }
    }

    /**
     * 用于定义通过字段索引获取字段数据时,如何把数据库类型转换为对应的Java类型
     * @param rs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public OrderStatusEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放int类型
        // String i = rs.getString(columnIndex);
        int i = rs.getInt(columnIndex);
        if (rs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的值,定位Enum子类
            return locateEnum(i);
        }
    }

    /**
     * 用定义调用存储过程后,如何把数据库类型转换为对应的Java类型
     * @param cs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public OrderStatusEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放int类型
        // String i = cs.getString(columnIndex);
        int i = cs.getInt(columnIndex);
        if (cs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的值,定位Enum子类
            return locateEnum(i);
        }
    }

    /**
     * 枚举类型转换
     * @param value 数据库中存储的自定义属性
     * @return value对应的枚举类
     */
    private OrderStatusEnum locateEnum(int value) {
        for (OrderStatusEnum status : OrderStatusEnum.values()) {
            if (status.getValue() == value) {
                return status;
            }
        }
        throw new IllegalArgumentException("未知的枚举类型:" + value);
    }
}

最后是使用
第一种方式:指定哪个类使用我们自己编写转换器进行转换,在MyBatis配置文件中配置如下:

<typeHandlers>
    <typeHandler handler="com.example.typeHandler.EnumOrderStatusHandler " javaType="com.example.entity.enums.OrderStatusEnum"/>
</typeHandlers>

第二种方式:修改指定xml文件,指定的Mapper生效

<result column="status" property="orderStatusEnum"
                typeHandler="com.example.typeHandler.EnumOrderStatusHandler"/>
<insert id="insert" parameterType="com.example.entity.OrderInfo">
        INSERT INTO
            order_test
            (status)
        VALUES (
            #{orderStatusEnum, typeHandler=com.example.typeHandler.EnumOrderStatusHandler, jdbcType=INTEGER}
        )
    </insert>

ps:通用转换处理器可以参考第三篇博客

参考文献

如何在MyBatis中优雅的使用枚举
Java、Mysql、MyBatis 中枚举 enum 的使用
mybatis枚举自动转换(通用转换处理器实现)

Spring Boot与MyBatis实战:自定义枚举类型转换器详解 MyBatis 的核心组件构成了其运行和数据交互的基础,理解这些组件的作用和相互关系,是掌握 MyBatis 使用的关键。枚举类型是 Java 5 引入的一种特殊类,用于表示一组固定的常量集合。在实际开发中,枚举被广泛应用于状态码、配置项、业务标识等场景。枚举常量默认为。枚举类默认继承类。应用场景枚举用途数据库字段类型枚举优点订单状态表示订单生命周期状态易于维护、类型安全用户性别表示用户性别信息。 阅读详情

相关推荐

mybatis中实现枚举自动转换方法详解

在使用mybatis的时候经常会遇到枚举类型的转换,下面这篇文章主要给大家介绍了关于mybatis中实现枚举自动转换的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧。

mybatis处理枚举转换

1从数据库返回的值转成指定的枚举类型–通过resultMap 指定typeHandler即可 <select id="listAll" resultMap="userMap"> select * from user </select> <resultMap id="userMap" type="com.taku.bean.User"> <result property="id" column="id"/>

weixin_45759287的博客 3008

C#教程

C# 教程 C# 是一个简单的、现代的、通用的、面向对象的编程语言,它是由微软(Microsoft)开发的。 本教程将告诉您基础的 C# 编程,同时将向您讲解 C# 编程语言相关的各种先进理念。 现在开始学习 C#! C# 在线工具 谁适合阅读本教程? 本教程有助于初学者理解基础的 C# 编程。在学习完本教程后,您将到达一个中级的 C# 编程水平。

zm1_1zm 1万+

mybatis mysql枚举类型转换_Mybatis枚举类映射使用详解

1. 前言刚入手spring-boot还不太熟练,先弄了个空的框架,然后写了个简单的用户查询,没啥挑战性。然后想起来之前一直对枚举不太了解,而用户的性别正好可以用枚举类型来表示(male, female)。于是就开始了自己的挖坑之旅。本文主要分为三个部分:mybatis自带枚举类型转换自定义枚举类型转换mybatis类型转换深入理解(将在下一篇介绍)2. mybatis自带枚举类型转换mybati...

weixin_34656543的博客 2066

VMware ESXi 7.0下Intel网卡SR-IOV配置实战:解决虚拟化网络延迟问题

本文详细介绍了在VMware ESXi 7.0环境下为Intel网卡配置SR-IOV(单根I/O虚拟化)的完整实战流程。通过硬件辅助直通技术,虚拟机可直接访问物理网卡资源,有效绕过虚拟化层瓶颈,从而显著降低网络延迟和CPU开销,适用于金融交易、实时计算等对性能敏感的场景。

embedding5hiker的博客 552

实战指南:基于Windows Server构建企业级AAA认证体系

本文详细介绍了如何在Windows Server环境下构建企业级AAA认证体系,涵盖AD域服务部署、NPS服务器配置及华为设备对接实战。通过整合Radius协议与AD域账号管理,实现网络设备的统一认证与权限控制,提升企业IT安全管理效率。特别适用于需要零成本实现AAA认证的中大型企业。

weixin_28304023的博客 420

Mybatis枚举类型转换

为项目中所有枚举类型定一个接口枚举类实现该接口@GetterDISBANDED("已解散", 0),NORMAL("正常", 1);定义通用枚举类型转换器();@Override@Override@Override@Override按照上述源码分析流程,当GroupStatusEnum第一次需要转化数据库的int时,mybatis去寻找类型转换器。我们没有为这种类型定义专门的类型转换器(TypeHandler)。该类不是内部类。

峰 1514

Windows下CMake的下载与安装详解

目录一、CMake介绍二、CMake的下载与安装 一、CMake介绍 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。它能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。 二、CMake的下载与安装 CMake下载链接:https://cmake.org/download/。 下载最新稳定版即可(Latest Release): 下载完成后,单击“Next”按钮,在下图中勾选“I acce

Wendy的博客 8万+

mybatis自定义枚举类型的转换器以及各种使用场景

mybatis自定义枚举类型的转换器以及各种使用场景

@素素~的博客 2385

STM32串口DMA双缓冲机制实战:提升数据传输效率的终极方案

本文深入解析了STM32串口DMA双缓冲机制的核心原理与实战配置。通过对比传统中断方式,阐述了双缓冲如何实现数据接收与处理的“无缝接力”,从而在工业传感器数据采集等高负载场景下,将CPU占用率降至极低水平并彻底避免数据丢失。文章提供了基于标准外设库的详细配置步骤、中断处理逻辑及性能实测数据,是提升嵌入式系统串口通信效率和可靠性的终极方案。

weixin_29192365的博客 78

基于FFT的阵列方向图快速计算公式推导

因为自己毕设涉及到阵列方向图综合相关知识,最近阅读了关于方向图综合的相关文献,就其中关于使用FFT计算阵列方向图的方法进行了公式推导。 简介: 自从1965年Colley-Tukey发表快速傅里叶变换[1]论文以来,FFT在许多科学技术领域获得了广泛和成功的应用。在阵列信号处理与雷达信号处理领域,随着科技的发展,对于电尺寸较大的相控阵天线,使用公式按照级数求和计算天线阵列方向图的方法效率甚低,...

qq_38151438的博客 4290

【第3章】Mybatis配置篇之类型别名、转换器和枚举类型

本章学习类型别名、类型转换器和处理枚举类型。你可以重写已有的类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 并且可以(可选地)将它映射到一个 JDBC 类型。回到顶部。

zjg 708

RK3568平台开发系列讲解(中断及异常篇)中断下半部:中断线程化

以前用 work 来线程化地处理中断,一个 worker 线程只能由一个 CPU 执行, 多个中断的 work 都由同一个 worker 线程来处理,在单 CPU 系统中也只能忍着 了。少数中断不能线程化,典型的例子是时钟中断,有些流氓进程不主动让出处理器,内核只能依靠周期性的时钟中断夺回处理器的控制权,时钟中断是调度器的脉搏。中断处理线程是优先级为50、调度策略是SCHED_FIFO的实时内核线程,名称是“irq/”后面跟着Linux中断号,线程处理函数是。,说明是线程化的中断,那么唤醒中断处理线程。

内核笔记 435

【mybatis】枚举类型转换器详解

https://blog.youkuaiyun.com/intersting/article/details/93768803 https://www.jb51.net/article/121690.htm

linchaoquande的专栏 451

基于反事实的因果推理Causal inference based on counterfactuals--一万六千字文献详细解读(因果关系的推理应用)【全文总结】

基于反事实的因果推理Causal inference based on counterfactuals--一万六千字文献详细解读(因果关系的推理应用)【全文总结】---来自一位即将入学的准研一,也希望这篇文章能够激励自己不断走下去!!

qq_46044325的博客 4441

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

mybatis-plus自定义数值类型枚举类转换器

mybatis-plus自定义数值类型枚举类转换器 MyBatis 内置了大部分基本类型的类型处理器,TypeHandler 类型处理器用于 JavaType 与 JdbcType 之间的转换。 所以对于基本类型可以直接处理,比如默认的这些IntegerTypeHandler,BigDecimalTypeHandler基本上不会去碰她。 当我们需要处理其他类型的时候,比如枚举类型,mybaits依然服务周到,提供两个常用的。 EnumOrdinalTypeHandler 每个枚举类中的值都自带下标,从0开始

numbbe的博客 3071

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Mybatis类型处理器,这个你得会玩!

id int AUTO_INCREMENT PRIMARY KEY COMMENT '用户id',name VARCHAR(32) NOT NULL DEFAULT '' COMMENT '用户名',age SMALLINT NOT NULL DEFAULT 1 COMMENT '年龄',sex SMALLINT DEFAULT 0 COMMENT '性别,0:未知,1:男,2:女') COMMENT '用户表';

weixin_45653328的博客111 648

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

java获取数据类型_重学Mybatis:类型处理器,这个你得会玩!

mybatis内部参数设置和结果的处理先来看一个案例:jdbc的方式插入用户信息,参数为UserModel:public class UserModel { private Integer id; private String name; private Integer age; //省略了get set方法 } public static int insert(...

weixin_39763293的博客 151

mybatis typeHandler

typeHandler是类型转换器。如果你需要将一个枚举类型的数据存放到数据库,而数据库不支持枚举类型,所以需要将它保存为一个数值类型。那么,如何实现数据库类型和java枚举类型的相互转换呢?使用自定义的类型转换器即可。自定义的类型转换器需要实现typeHandler接口。

iAm333的专栏 6151

SpringMVC对枚举类型输入输出及Mybatis对枚举类型的存储查询

文章目录摘要准备环境Spring MVC接收枚举类型Spring MVC输出枚举类型MyBatis存储查询枚举类型测试 摘要 本文使用SpringBoot.2.0.1.RELEASE进行快速搭建项目,数据库采用内存数据H2,使用性别枚举作为例子讲解SpringMVC及Mybatis枚举类型处理。 准备环境 maven依赖 加入如下依赖后,SpringBoot自动配置H2数据库作为数据源,Mybat...

东京易冷 1448

springboot + mybatis 自定义枚举类型转换

MyBatis内置了两个枚举转换器分别是:org.apache.ibatis.type.EnumTypeHandler和org.apache.ibatis.type.EnumOrdinalTypeHandler。 EnumTypeHandler是默认的枚举转换器,该转换器将枚举实例转换为实例名称的字符串。比如有个枚举 NO_RECOVERY(10),使用EnumTypeHandler保存在数据...

weixin_30273931的博客 570

学习Spring Boot:(十二)Mybatis 中自定义枚举转换器

https://blog.wuwii.com/springboot-12.html 前言 在 Spring Boot 中使用 Mybatis 中遇到了字段为枚举类型,数据库存储的是枚举的值,发现它不能自动装载。 解决 内置枚举转换器 MyBatis内置了两个枚举转换器分别是:org.apache.ibatis.type.EnumTypeHandler和org.apac...

weixin_30404405的博客 298

mybatis mysql enum_如何在MyBatis中优雅的使用枚举

问题在编码过程中,经常会遇到用某个数值来表示某种状态、类型或者阶段的情况,比如有这样一个枚举:public enum ComputerState {OPEN(10), //开启CLOSE(11), //关闭OFF_LINE(12), //离线FAULT(200), //故障UNKNOWN(255); //未知private int code;...

weixin_42513601的博客 613

java获取数据类型_重学Mybatis:类型处理器,这个你得会玩

推荐学习真香警告!Alibaba珍藏版mybatis手写文档,刷起来 10.24程序员节,喜得一套「MySQL性能优化金字塔法则」 mybatis内部参数设置和结果的处理先来看一个案例:jdbc的方式插入用户信息,参数为UserModel:public class UserModel { private Integer id; private String name; priva...

weixin_39971435的博客 127

mybatis中的枚举使用

原文地址如何在MyBatis中优雅的使用枚举 抛出异常:Incorrect integer value: ‘ON’ for column ‘status’ at row 1; nested exception is java.sql.SQLException: Incorrect integer value: ‘ON’ for column ‘status’ at row 1。 在mybatis处理枚举类型时,数据库存的是枚举的code,这个时候再数据类型转换的时候就要报错了。于是百度到这篇文章,在这里转载

小小的人儿的博客 3135

重学Mybatis:类型处理器,这个你得会玩!

这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!!《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!” />这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!![外链图片转存中…(img-4R3WosOL-1712521473712)]《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》

A1867350的博客 1158
上一篇: Java线程状态转换详解
下一篇: mysql采坑之count distinct多列
山木枝
博客等级 码龄11年 8粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值