MyBatis里字段到枚举类的映射

一、简介

  我们在用MyBatis里,很多时间有这样一个需求:bean里有个属性是枚举,在DB存储时我们想存的枚举的代号,从DB拿出来时想直接映射成目标枚举类型,也即代号字段与Java枚举类的相互类型转换

  当然,你可以为每个枚举写一个MyEnumTypeHandler,但问题是要为每个类都写一个TypeHandler,过于繁琐。

  有了泛型,一个通用的TypeHandler直接搞定。

二、源码

源码详见:spring-mybatis-test

package com.adu.spring_test.mybatis.typehandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

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

import com.adu.spring_test.mybatis.enums.EnumTrait;
import com.adu.spring_test.mybatis.util.EnumTraitUtil;

/**
 * mapper里字段到枚举类的映射。
 * 用法:
 * 入库:#{item.myEnum, typeHandler=com.adu.spring_test.mybatis.typehandler.EnumTraitTypeHandler}
 * 出库:
 * <resultMap>
 * <result property="enumDataField" column="enum_data_field" javaType="com.xxx.MyEnum" typeHandler="com.adu.spring_test.mybatis.typehandler.EnumTraitTypeHandler"/>
 * </resultMap>
 */
public class EnumTraitTypeHandler<E extends EnumTrait> extends BaseTypeHandler<EnumTrait> {

    private Class<E> type;

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

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, EnumTrait parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setInt(i, parameter.getCode());
    }

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

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

    private E fromCode(int code) {
        return EnumTraitUtil.codeOf(type, code);
    }
}

  

时间: 2024-10-12 18:52:54

MyBatis里字段到枚举类的映射的相关文章

MyBatis里json型字段到Java类的映射

一.简介 我们在用MyBatis里,很多时间有这样一个需求:bean里有个属性是非基本数据类型,在DB存储时我们想存的是json格式的字符串,从DB拿出来时想直接映射成目标类型,也即json格式的字段串字段与Java类的相互类型转换. 当然,你可以为每个类写一个MyClassTypeHandler,但问题是要为每个类都写一个TypeHandler,过于繁琐. 有了泛型,一个通用的TypeHandler直接搞定. 二.源码 package com.xxx.typehandler; import c

Java 之枚举类

在某些情况下,一个类的对象是有限而且是固定的,比如季节类,它只有4个对象.这种实例有限而且固定的类,在Java里被称为枚举类. 在早期,可能会直接使用简单的静态常量来表示枚举类,例如: public static final int SEASON_SPRING = 1; public static final int SEASON_SUMMER = 2; public static final int SEASON_FAIL = 3; public static final int SEASON

【Java基础08】内部类、枚举类、日期和时间、Math、Random

1 内部类 1.1 概念 大部分时候,类被定义成一个独立的程序单元,在某些情况下,也会把一个类放到另一个类的内部定义,这个定义在其他类内部的类就被称为内部类,包含内部类的类被称为外部类. 1.2 作用 1.提供更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类. 2.内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问.但外部类不能访问内部类的实现细节,例如内部类的成员变量. 3.匿名内部类适合用于创建那些仅需要一次使用的类

使用内部枚举类作为外部类的参数的Mybatis的参数该如何判断

新写了一个接口,期望根据不同的参数来给数据库中不同的字段进行传值.这里使用了内部静态枚举类的方式进行传值,在写mybatis动态sql时,如果是普通对象,一般使用,那么使用枚举类,如何判断枚举类的值呢? Mapper接口 public class SLineSboxesQueryParam { private QueryMethod queryMethod;//查询方式的枚举内部类 private List<String> idList; private LocalDateTime start

MyBatis Spring整合配置映射接口类与映射xml文件

Spring整合MyBatis使用到了mybatis-spring,在配置mybatis映射文件的时候,一般会使用MapperScannerConfigurer,MapperScannerConfigurer会自动扫描basePackage指定的包,找到映射接口类和映射XML文件,并进行注入.配置如下: [html] view plain copy <!-- 数据源 --> <bean id="dataSource" class="com.mchange.v

Mybatis配置文件和实体类的映射文件,以及dao层的书写

mybatis-config.xml,配置文件,用于连接数据库.底层使用的是oracle数据库的emp表 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-config.dtd&

自订类的属性与字段如何枚举并提供控件作为系结来源?

我在" 数组详论"与"Enum详论"两篇文章中曾经介绍过如何将数组以及 Enum 项目当作系结控件的数据来源.然而,无论是数组或是 Enum 项目, 它们都有设定和使用上的巨大限制.其中, Enum 的每个项目都必须是常值, 换句话说, 项目的值无法动能控制.而数组的值虽然可以动态变更, 但无法提供设计时的 Intellisense 支持... 我在" 数组详论"与"Enum详论"两篇文章中曾经介绍过如何将数组以及 Enum

No enum constant org.apache.ibatis.type.JdbcType.Integer 【找不到这个枚举类,mybatis相关】

同事今天在用mybatis查询时候,报了上面这个问题.上网查了下,原来是mybatis封装类型的问题.原因是在resultMap中jdbcType写为了Integer,但是在MyBatis中没有这个数据类型 来查看了原码,发现MyBatis的jdbcType是一个枚举类,有以下类型: public enum JdbcType { ARRAY(2003), BIT(-7), TINYINT(-6), SMALLINT(5), INTEGER(4), BIGINT(-5), FLOAT(6), RE

Mybatis学习总结(六)——高级映射(一对一,一对多,多对多)

一.订单商品数据模型 1.数据库执行脚本 创建数据库表代码: /*Table structure for table `t_user` */ CREATE TABLE t_user ( id INT NOT NULL AUTO_INCREMENT, username VARCHAR(32) NOT NULL COMMENT '用户名称', birthday DATE DEFAULT NULL COMMENT '生日', sex CHAR(1) DEFAULT NULL COMMENT '性别',