专栏首页用户1337634的专栏自定义枚举 --- MyBatis字段映射

自定义枚举 --- MyBatis字段映射

MyBatis自带的EnumTypeHandler转换为文字保存在数据库,EnumOrdinalTypeHandler使用的是序号,它们的一致性都可能被轻易地破坏,所以最好的办法是自定义一个int类型

自定义公共父接口

package com.tenmao.utils.mybatis;

import java.util.Arrays;
import java.util.Optional;

public interface CodedEnum {
    int getCode();

    static <E extends Enum<?> & CodedEnum> Optional<E> codeOf(Class<E> enumClass, int code) {
        return Arrays.stream(enumClass.getEnumConstants()).filter(e -> e.getCode() == code).findAny();
    }
}

Enum的转换工具类

package com.tenmao.utils.mybatis.handler;

import com.tenmao.utils.mybatis.CodedEnum;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

import java.sql.*;
import java.util.Optional;

@MappedTypes({CodedEnum.class})
public class CodedEnumTypeHandler<E extends Enum<?> & CodedEnum> implements TypeHandler<E> {
    private Class<E> type;

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

    @Override
    public void setParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null) {
            ps.setNull(i, Types.TINYINT);
        } else {
            ps.setInt(i, parameter.getCode());
        }
    }

    @Override
    public E getResult(ResultSet rs, String columnName) throws SQLException {
        int columnValue = rs.getInt(columnName);
        return rs.wasNull() ? null : enumOf(columnValue);
    }

    @Override
    public E getResult(ResultSet rs, int columnIndex) throws SQLException {
        int columnValue = rs.getInt(columnIndex);
        return rs.wasNull() ? null : enumOf(columnValue);
    }

    @Override
    public E getResult(CallableStatement cs, int columnIndex) throws SQLException {
        int columnValue = cs.getInt(columnIndex);
        return cs.wasNull() ? null : enumOf(columnValue);
    }

    private E enumOf(int code) {
        final Optional<E> codedEnumOpt = CodedEnum.codeOf(type, code);
        if (codedEnumOpt.isPresent()) {
            return codedEnumOpt.get();
        } else {
            throw new IllegalArgumentException("Cannot convert " + code + " to " + type.getSimpleName() + " by code value.");
        }
    }
}

配置使用转换工具类

data-applicationContext.xml

    <bean id="data-sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="mapperLocations">
            <list>
                <value>classpath*:mapper/*Mapper.xml</value>
            </list>
        </property>
        <property name="dataSource" ref="data-datasource" />
        <property name="configuration" ref="mybatisConfig" />
        <property name="typeHandlersPackage" value="com.tenmao.utils.mybatis.handler" />
    </bean>

自定义枚举

package com.tenmao.utils.model;

import com.tenmao.utils.mybatis.CodedEnum;

public enum Weekday implements CodedEnum {
    MONDAY(1),
    TUESDAY(2),
    WEDNESDAY(3),
    THURSDAY(4),
    FRIDAY(5),
    SATURDAY(6),
    SUNDAY(7)
    private final int code;

    Weekday (int code) {
        this.code = code;
    }

    @Override
    public int getCode() {
        return code;
    }
}

ps: 参考资料写得特别好,我之所以重新写了一下,是资料写得有点啰嗦,比如子类的注册,其实都是自动的,不需要再额外配置

自定义枚举系列

参考

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Upsource实现Intellij IDEA上的Code Review

    https://www.jetbrains.com/upsource/download 下载后解压

    十毛
  • Spring Cloud Gateway快速体验

    GlobalFilter只要注册到Spring容器,就可以应用在所有请求,比如监控请求耗时

    十毛
  • 数据库一个字段保存多标志位

    十毛
  • 第三阶段-Java常见对象:【第八章 System类】

    System.gc() 可用于垃圾回收.当使用System.gc() 回收某个对象所占用的内存之前,通过要求程序调用适当的方法来清理资源,在没有明确指定资源清理...

    BWH_Steven
  • 重构

    最近公司做了个项目,深深体会到架构设计以及代码优化有多么的重要。 回头看自己的代码都觉得特别混乱,有时候还要看很久才能看懂,可扩展性特别差,完全是为了完成需求而...

    用户3467126
  • Kafka之拦截器Interceptor

        使用场景:我们可以在Producer端统一拦截,加上处理时间,再在consumer端统一拦截统计端到端的处理时间,这也是一种监控方式。

    克虏伯
  • 曾经做过的40道程序设计课后习题总结(四)

    曾经做过的40道程序设计课后习题总结(四) 课后习题目录 1 斐波那契数列 2 判断素数 3 水仙花数 4 分解质因数 5 杨辉三角 6 学习成绩查询...

    闵开慧
  • Jtro的技术分享:游戏客户端与服务器(c#)通讯_异步Socket

    首先跟大家道个歉,上一个同步Socket文章里用的不是Markdown编写的,所以代码看起来不是很清爽,我用的鹅厂的浏览器,终于发现是浏览器的锅,图片拖不上去 ...

    LittleU
  • Android仿QQ首页ListView左滑置顶、删除功能

    实现源码:package com.duguang.baseanimation.ui.listivew.deletelistview;

    砸漏
  • Android编程实现的首页左右滑动切换功能示例

    本文实例讲述了Android编程实现的首页左右滑动切换功能。分享给大家供大家参考,具体如下:

    砸漏

扫码关注云+社区

领取腾讯云代金券