Mybatis处理枚举

2023-11-15

Springboot 集成 Mybatis 处理枚举
mybatis自带了两个处理枚举的 类 EnumTypeHandler ,EnumOrdinalTypeHandler 一个使用枚举的name,一个使用枚举的下标;
做项目时,会节省数据库资源,对一些固定的值,直接在代码里定义为枚举,枚举存放一个code 将这个code存入数据库; 比如男女 存放1 ,0 而不是男女这两个字;
处理这些枚举的时候需要我们自定义枚举处理;

两种实现方案:
定义接口 BaseEnum

public interface BaseEnum {
    String getValue();
}

这里定义为String类型;因为在jdbc里面String基本能映射大多数数据库数据类型
也可以使用其他类型
定义枚举类型处理器

/**
 * 使用BaseEnum 指定枚举会映射的数据
 * @param <E> BaseEnum
 * @author jian.jiang
 * 处理枚举映射
 */
@MappedTypes(BaseEnum.class)
public class EnumTypeHandler<E extends Enum<E>&BaseEnum> extends BaseTypeHandler<E> {

    private final HashMap<String, E> eMap = new HashMap<>();

    public EnumTypeHandler(Class<E> type) {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }

        for (E e : type.getEnumConstants()) {
            eMap.put(e.getValue(), e);
        }
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType)
            throws SQLException {
        if (jdbcType == null)
            ps.setString(i, parameter.getValue());
        else
            ps.setObject(i, parameter.getValue(), jdbcType.TYPE_CODE);
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName)
            throws SQLException {
        return eMap.get(rs.getString(columnName));
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex)
            throws SQLException {
        return eMap.get(rs.getString(columnIndex));
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return eMap.get(cs.getString(columnIndex));
    }
}

更改配置


mybatis:
  mapper-locations: classpath:**/mapper/*.xml,classpath:**/dao/*.xml
  configuration:
    default-enum-type-handler: demo.mybatis.typehandler.EnumTypeHandler

这里的配置default-enum-type-handler会替换掉TypeHandlerRegistry 里面的defaultEnumTypeHandler

枚举定义时实现BaseEnum接口就可以了,例如:

@AllArgsConstructor
@Getter
public enum SexEnum implements BaseEnum {
    MAN(1),
    WOMAN(0),
    UNKNOW(2),
    ;

    @JsonValue
    public final Integer code;


    @Override
    public String getValue() {
        return code.toString();
    }
}

如果项目中使用rest接口,返回前端时,枚举也需要转为指定的Code,一般会使用@JsonValue注解
可以借助这个注解,省去再写接口,实现接口的步骤

定义枚举处理器


/**
 * 与页面vo共用一个注解
 * @author jianjiang
 */
public class JsonEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {

    private final Map<String, E> key2value = new HashMap<>();
    private final Map<E, String> value2key = new HashMap<>();

    public JsonEnumTypeHandler(Class<E> type) throws IllegalAccessException {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }

        E[] enumConstants = type.getEnumConstants();
        Field[] declaredFields = type.getDeclaredFields();
        Field jsonValue = null;
        int count = 0;
        for (Field e : declaredFields) {
            if (e.isAnnotationPresent(JsonValue.class)) {
                jsonValue = e;
                count++;
            }
        }

        if (count > 1) {
            throw new IllegalArgumentException("exist more than one  Annotation JsonValue" + type.getName());
        } else if (count == 1) {
            if (!jsonValue.isAccessible())
                    jsonValue.setAccessible(true);  
            for (E e : enumConstants) {
                key2value.put(String.valueOf(jsonValue.get(e)), e);
                value2key.put(e, String.valueOf(jsonValue.get(e)));
            }
        } else { //如果没有,按照name进行设置
            for (E e : enumConstants) {
                key2value.put(e.name(), e);
                value2key.put(e, e.name());
            }
        }
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        if (jdbcType == null) {
            ps.setString(i, value2key.get(parameter));
        } else {
            ps.setObject(i, value2key.get(parameter), jdbcType.TYPE_CODE);
        }
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String s = rs.getString(columnName);
        return s == null ? null : key2value.get(s);
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String s = rs.getString(columnIndex);
        return s == null ? null : key2value.get(s);
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String s = cs.getString(columnIndex);
        return s == null ? null : key2value.get(s);
    }
}

配置那替换为这个类

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mybatis处理枚举 的相关文章

随机推荐

  • 查找---散列表查找定义

    当我们进行查找时 如果是顺序表查找 要找的关键字的记录 是从表头开始 挨个的比较记录a i 与key的值是等于还是不等于 有序表查找时 利用折半查询或者插值查询 直到相等时成功返回i 最终我们的目的都是为了找到那个i 其实也就是相对的下标
  • 使用TortoiseGit

    初衷 脱离命令行的方式 使用gui的界面化工具完成工作需要的版本控制操作 同时还对git运行机制有一定的了解 达到工作需要的基本 提高工作效率 准备工作 安装git 至于为什么 我就不废话了 点我下载git 安装TortoiseGit 理由
  • 【vue3引入高德地图】

    vue3引入高德地图 文章目录 vue3引入高德地图 前言 一 准备工作 1 开发文档 2 添加应用 二 使用步骤 1 npm 安装 2 地图容器创建 3 组件引入 4 js api 安全密钥 5 初始化地图 6 图层 6 1 添加 设置
  • 在 Windows 10 编译 Qt 5.15

    译好的下载链接 Qt5 15 8 Windows x86 VS2017 Qt5 15 8 Windows x86 64 VS2017 Qt5 15 8 Windows x86 VS2019 Qt5 15 8 Windows x86 64 V
  • 【Unity】通过代码控制编译器的暂停

    暂停编译器 EditorApplication isPaused true 结束编译器 EditorApplication isPlaying false
  • sklearn决策树之random_state & splitter

    在上一篇博文 决策树的sklearn实现 中 我们建立了一棵完整的决策树 但是如果在建立模型时不设置random state的数值 score会在某个值附近波动 引起画出来的每一棵树都 一样 它为什么会 稳定呢 如果使用其他数据集 它还会不
  • 互斥机制之自旋锁(spinlock)

    一 基础 自旋锁 如果测试结果表明锁仍被占用 程序将在一个小的循环内重复这个 测试并设置 操作 即进行所谓的 自旋 1 定义自旋锁 spinlock t spin 2 初始化自旋锁 spin lock init lock 该宏用于动态初始化
  • 【论文笔记】Masked Autoencoders Are Scalable Vision Learners

    论文 论文标题 Masked Autoencoders Are Scalable Vision Learners 发表于 CVPR2021 论文链接 https arxiv org pdf 2111 06377 pdf 论文代码 https
  • WebGL学习系列-片元着色器简介

    前言 到目前为止 我们绘制过点 三角形 矩形等 但使用的都是单色系 之前曾经说过着色器的概念 着色器分为顶点着色器和片元着色器 我们一直在使用顶点着色器 而对片元着色器基本没有提及过 本小节将展开对片元着色器的简单介绍 彩色的点 之前提到过
  • Sybase IQ常用函数大全--杂项函数

    Sybase IQ常用函数大全 杂项函数 查询索引 COALESCE 函数 返回列表中的第一个非 NULL 表达式 IFNULL 函数 返回第一个非空值表达式或 NULL ISNULL 函数 返回参数列表中的第一个非 NULL 表达式的值
  • 笔记~【软件测试基础知识】——黑盒测试和白盒测试

    这里写目录标题 一 黑盒测试 二 白盒测试 一 黑盒测试 黑盒测试概述 黑盒测试也称功能测试或数据驱动测试 它已知产品所应具有的功能 通过测试来检测每个功能是否能够正常使用 主要针对软件界面和软件功能 在测试时 把程序看作一个不能打开的黑盒
  • cv::Mat的翻转和转置

    cv Mat的本质是矩阵 openCV对Mat类型的处理 实际上也是矩阵操作 这里给个小例子 介绍转置操作和翻转操作 这段代码受了 http www tuicool com articles emIr2u 的启发 原图 Mat m1 imr
  • 【数据预处理】Pandas缺失的数据处理

    目录 缺少数据基础 何时 为何 数据丢失 被视为 缺失 的值 日期时间 插入缺失数据 缺少数据的计算 Sum Prod of Empties Nans GroupBy中的NA值 清理 填写缺失数据 填充缺失值 fillna 用PandasO
  • flutter -- 自定义音乐播放器/视频播放器

    写在前头 flutter 自定义实现音乐播放的文章挺多的 但是在开发中还是碰见了超级无语的情况 没想到需求竟然要音频的1倍到2倍的播放倍速 我一度质疑这个功能的实际用途 但是既然提出来了 开发就得撅屁股实现 这里采用了第三方的视频播放器来实
  • 如何使用BurpSuite(后续)

    前面那篇文章是我前几天写的 我发现我把简单的问题弄得复杂了 今天我给大家再写一篇关于BurpSuite的使用 1 下载安装免费版或者收费版 这里就不演示了 2 运行软件 一直NEXT就可以 3 打开工具 此时拦截状态显示OFF 4 在打开的
  • Python中类成员变量与实例成员变量相互影响的原因超详细解释

    今天在看python学习手册时看到了两句话 一 第26章中 类对象提供默认行为 二 第26章中 实例对象是具体的元素 书中给的例子是这样的 但上网查了一下好像第二句话不是非常准确 如下面的文章 原文 https www jb51 net a
  • 优化算法学习(LM算法)

    文章目录 推荐书籍 理论理解 程序实现 ceres安装 代码 推荐书籍 建议学习 METHODS FOR NON LINEAR LEAST SQUARES PROBLEMS http www2 imm dtu dk pubdb views
  • Eclipse导入Maven项目,实在算得上是历经千辛万苦

    私下接触了一个项目 架构师那边用的是idea 并且是一个Maven项目 架构师说他那边idea可以自动将Maven项目转换为Web项目 但我已经习惯用Eclipse了 所以还需要自己动手试一试 这一试 一上午的时间算是过去了 尤其是中间遇到
  • 商品关联度分析(关联三度,附Python实战) 我的钱就是这么没的,不只有皮尔森系数的相关分析

    引言 上一年组织烧烤活动买食材时 我在超市的货架29买了一个烧烤架 然后到货架27买了瓶1 5L的可乐 最后在货架25找到了我需要的塑料小碗 今年再去那家超市的时候 特地再去烧烤架所在的货架查看了一下 看看有没有什么值得记录的灵感 果不其然
  • Mybatis处理枚举

    Springboot 集成 Mybatis 处理枚举 mybatis自带了两个处理枚举的 类 EnumTypeHandler EnumOrdinalTypeHandler 一个使用枚举的name 一个使用枚举的下标 做项目时 会节省数据库资