资讯专栏INFORMATION COLUMN

mybatis处理枚举类

caspar / 1598人阅读

摘要:自带对枚举的处理类该类实现了枚举类型和类型的相互转换。而在具体中也需要使用属性,如在处理到该位置时,就会调用指定的处理类来处理枚举类型。

mybatis自带对枚举的处理类

org.apache.ibatis.type.EnumOrdinalTypeHandler :该类实现了枚举类型和Integer类型的相互转换。

但是给转换仅仅是将对应的枚举转换为其索引位置,也就是"ordinal()"方法获取到的值。对应自定义的int值,该类无能为力。

org.apache.ibatis.type.EnumTypeHandler:该类实现了枚举类型和String类型的相互转换。

对于想将枚举在数据库中存储为对应的int值的情况,该类没办法实现。

基于以上mybatis提供的两个枚举处理类的能力有限,因此只能自己定义对枚举的转换了。

自定义mybatis的枚举处理类EnumValueTypeHandler

该类需要继承org.apache.ibatis.type.BaseTypeHandler,然后在重定义的方法中实现自有逻辑。

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.MappedTypes;

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

/**
 * 处理实现了{@link EsnBaseEnum}接口的枚举类
 * @author followtry
 * @time 2016年8月16日 下午8:06:49
 * @since 2016年8月16日 下午8:06:49
 */
 //在 xml 中添加该 TypeHandler 时需要使用该注解
@MappedTypes(value = {
        QcListTypeEnum.class,
        SellingQcBizTypeEnum.class
})
public class EnumValueTypeHandler extends BaseTypeHandler {

    private Class type;

    private final E[] enums;

    public EnumValueTypeHandler(Class 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 {
        //获取非空的枚举的int值并设置到statement中
        ps.setInt(i, parameter.getValue());
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        int i = rs.getInt(columnName);
        if (rs.wasNull()) {
            return null;
        } else {
            try {
                return getEnumByValue(i);
            } catch (Exception ex) {
                throw new IllegalArgumentException(
                        "Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex);
            }
        }
    }

    /**
     * 通过枚举类型的int值,获取到对应的枚举类型
     * @author jingzz
     * @param i
     */
    protected E getEnumByValue(int i) {
        for (E e : enums) {
            if (e.getValue() == i) {
                return e;
            }
        }
        return null;
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        int i = rs.getInt(columnIndex);
        if (rs.wasNull()) {
            return null;
        } else {
            try {
                return getEnumByValue(i);
            } catch (Exception ex) {
                throw new IllegalArgumentException(
                        "Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex);
            }
        }
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        int i = cs.getInt(columnIndex);
        if (cs.wasNull()) {
            return null;
        } else {
            try {
                return getEnumByValue(i);
            } catch (Exception ex) {
                throw new IllegalArgumentException(
                        "Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex);
            }
        }
    }

}

该处理器是处理继承了EsnBaseEnum接口的枚举类,因为该接口中定义了获取自定义int值的方法。

如果在 mybatis 的 xml 中配置 该 typehandler,则需要添加注解@MappedTypes。在添加 typeHandler 注册时使用具体的实现类注册。

配置文件如下:



    


    
    

自定义的 Enum 需要实现的接口

/**
 * @author jingzz
 * @time 2016年8月17日 上午9:22:46
 * @since 2016年8月17日 上午9:22:46
 */
public interface EsnBaseEnum {
    
    public int getValue();
}

而实现了EsnBaseEnum的枚举示例如下:

/**
 * 同步的类型
 * @author jingzz
 * @time 2016年8月3日 上午11:13:06
 */
public enum SyncType implements EsnBaseEnum {
    
    DEPT(3),//部门
    PERSON(1);//人员
    
    private int value;
    
    private SyncType(int value) {
        
        this.value = value;
    }
    
    @Override
    public int getValue(){
        return this.value;
    }
}

只有在实现了EsnBaseEnum的接口,EnumValueTypeHandler才能通过接口的getValue方法获取到对应枚举的值。

到此,对于枚举的简单处理逻辑已经实现完成了,接下来就是如何配置来使用该自定义枚举处理逻辑

配置对枚举的处理

首先,mybatis中对于处理逻辑的设置是在sql的映射文件中,如EsnSyncLogMapper.xml

关键的设置枚举处理的位置如下:


    
    
    
    
    
    
  

其中type列设置了属性typeHandler,其值为自定义的枚举处理逻辑。

而在具体sql中也需要使用typeHandler属性,如:

 
    #{type, typeHandler=com.test.common.EnumValueTypeHandler},
  

在mybatis处理到该位置时,就会调用typeHandler指定的处理类来处理枚举类型。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77673.html

相关文章

  • 使用MyBatis简化枚举值的存储和读取

    摘要:内置的枚举处理器为了处理上述遇到的问题,内置了两种,分别是和。将使用枚举实例的值序数值,从开始来和枚举类之间做转换。比如有记录显式为全局指定在查询时,类变量将自动赋值为,添加记录时同理,数据库值将存储为其枚举类实例序号。 场景描述 我们在实际场景中经常会遇到需要将枚举值存储到数据库中,或是将从数据库中查询到的值对应到枚举类上的情况。 比如表process大致定义如下: -- -----...

    Bryan 评论0 收藏0
  • 如何在MyBatis中优雅的使用枚举

    摘要:如何解决呢在中我们可以使用方式来干预的创建过程,来完成转换器的指定。再也不用写的配置文件了结束了以上就是我对如何在中优雅的使用枚举的探索。 问题 在编码过程中,经常会遇到用某个数值来表示某种状态、类型或者阶段的情况,比如有这样一个枚举: public enum ComputerState { OPEN(10), //开启 CLOSE(11), ...

    clasnake 评论0 收藏0
  • MyBatis 源码分析系列文章导读

    摘要:本文速览本篇文章是我为接下来的源码分析系列文章写的一个导读文章。年该项目从基金会迁出,并改名为。同期,停止维护。符号所在的行则是表示的执行结果。同时,使用无需处理受检异常,比如。另外,把写在配置文件中,进行集中管理,利于维护。 1.本文速览 本篇文章是我为接下来的 MyBatis 源码分析系列文章写的一个导读文章。本篇文章从 MyBatis 是什么(what),为什么要使用(why),...

    weizx 评论0 收藏0
  • mybatis动态sql

    摘要:枚举类型提供了提供了持久化的枚举类型。假设表结构的列,使用类型存储或,对象使用枚举类型标识当执行语句时,或会存储到列,如果想要存储的时枚举值而不是枚举名字,就需要配置类型处理器和提供了对和的内检支持,将映射为,将映射为数组。 mybatis中静态sql语句有时不足以满足用户的需求,因此其提供了动态sql标签。 IF标签 if标签通过条件测试,动态插入sql片段,例如: an...

    anyway 评论0 收藏0
  • 一起来学SpringBoot | 第八篇:通用Mapper与分页插件的集成

    摘要:通用是为了解决使用中的基本操作,使用它可以很方便的进行开发,可以节省开发人员大量的时间。当该参数设置为时,时会查询第一页,超过总数时,会查询最后一页。 SpringBoot 是为了简化 Spring 应用的创建、运行、调试、部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖就可以轻易的搭建出一个 WEB 工...

    韩冰 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<