mybatis自定义类型处理器

本文详细介绍了如何在MyBatis中创建并启用自定义类型处理器,以解决Java枚举与数据库列类型转换的问题。通过示例展示了如何编写 GenderEnum 类型处理器,并提供了三种启用方式:配置类注册、配置文件指定包路径和在SQL中直接指定。此外,还给出了XML和注解方式的SQL示例。
摘要由CSDN通过智能技术生成

mybatis自定义类型处理器


相关说明

本文以java枚举GenderEnum与数据库表列类型char相互转换为例进行示例说明。

  • 现有Employee类

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class Employee {
        
        /** 名字 */
        private String name;
        
        /** 年龄 */
        private Integer age;
        
        /** 性别 */
        private GenderEnum gender;
        
        /** 座右铭 */
        private String motto;
        
    }
    
  • Employee类对应的表结构为
    在这里插入图片描述

编写类型处理器

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

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

/**
 * 自定义类型装换器:<br/>
 * <ul>
 *     <li>方式一:继承{@link BaseTypeHandler}</li>
 *     <li>方式二:实现{@link TypeHandler}</li>
 * </ul>
 *
 * <br><br>
 * <p>
 * 哪些类型可以相互转换,可通过{@link MappedTypes}和{@link MappedJdbcTypes}进行指定:<br/>
 * <ul>
 *     <li>{@link MappedTypes}指定java类型</li>
 *     <li>{@link MappedJdbcTypes}指定jdbc类型</li>
 * </ul>
 *
 * @author JustryDeng
 * @since 2021/9/12 15:49:44
 */
@MappedTypes(value = {GenderEnum.class})
@MappedJdbcTypes(value = {JdbcType.CHAR})
public class GenderEnumHandler extends BaseTypeHandler<GenderEnum> {
    
    /**
     * 入库时调用
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, GenderEnum parameter, JdbcType jdbcType) throws SQLException {
        // 具体调用ps的什么setXxx方法,要看你的数据类型
        ps.setInt(i, parameter.getGender());
    }
    
    /**
     * 出库时调用
     */
    @Override
    public GenderEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 具体调用rs的什么getXxx方法,要看你的数据类型
        int i = rs.getInt(columnName);
        if (i == 0) {
            return GenderEnum.WOMAN;
        }
        if (i == 1) {
            return GenderEnum.MAN;
        }
        throw new IllegalArgumentException("GenderEnum un-support gender " + i);
    }
    
    /**
     * 出库时调用
     */
    @Override
    public GenderEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        // 具体调用rs的什么getXxx方法,要看你的数据类型
        int i = rs.getInt(columnIndex);
        if (i == 0) {
            return GenderEnum.WOMAN;
        }
        if (i == 1) {
            return GenderEnum.MAN;
        }
        throw new IllegalArgumentException("GenderEnum un-support gender " + i);
    }
    
    /**
     * 出库时调用
     */
    @Override
    public GenderEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        // 具体调用rs的什么getXxx方法,要看你的数据类型
        int i = cs.getInt(columnIndex);
        if (i == 0) {
            return GenderEnum.WOMAN;
        }
        if (i == 1) {
            return GenderEnum.MAN;
        }
        throw new IllegalArgumentException("GenderEnum un-support gender " + i);
    }
}

启用类型处理器

方式一:直接用mybatis总配置类注册处理器

import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * mybatis类型处理器配置
 *
 * @author JustryDeng
 * @since 2021/9/12 16:34:45
 */
@Component
public class MybatisTypeHandlerConfig {
    
    final List<SqlSessionFactory> sqlSessionFactoryList;
    
    public MybatisTypeHandlerConfig(@Autowired List<SqlSessionFactory> sqlSessionFactoryList) {
        this.sqlSessionFactoryList = sqlSessionFactoryList;
    }
    
    @PostConstruct
    public void initHandler () {
        if (sqlSessionFactoryList == null) {
            return;
        }
        sqlSessionFactoryList.forEach(sqlSessionFactory -> {
            sqlSessionFactory.getConfiguration().getTypeHandlerRegistry().register(GenderEnumHandler.class);
        });
    }
}

方式二:通过配置文件指定处理器所处的包

# springboot项目,可通过指定处理器所在包(或祖先包)来启动处理器
mybatis.type-handlers-package=com.example.mybatis.handler

注:如果项目用了mybatis-plus,那么mybatis.type-handlers-package可能会失效,此时可以通过mybatis-plus.type-handlers-package来指定。

方式三:在编写SQL时,指定类型处理器

  • 使用xml写sql时

    <insert id="insertByXml">
        insert into employee(`name`, `age`, `gender`, `motto`)
        values (#{e.name}, #{e.age}, #{e.gender,typeHandler=com.example.mybatis.handler.GenderEnumHandler}, #{e.motto})
    </insert>
        
    <select id="selectByXml" resultMap="selectByXmlRM">
        select `name`, age, gender, motto
        from employee
        order by id desc limit 1
    </select>
    
    <resultMap id="selectByXmlRM" type="com.example.mybatis.model.Employee">
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="gender" column="gender" typeHandler="com.example.mybatis.handler.GenderEnumHandler"/>
        <result property="motto" column="motto"/>
    </resultMap>
    
  • 使用注解写sql时

    @Insert("insert into employee(`name`, `age`, `gender`, `motto`) values "
            + "(#{e.name}, #{e.age}, #{e.gender,typeHandler=com.example.mybatis.handler.GenderEnumHandler}, #{e.motto})")
    int insert(@Param("e") Employee e);
    
    @Select("select `name`,age,gender,motto from employee order by id desc limit 1")
    @Results(value = {
            // 其余查询列没有啥特殊性的,可不指定@Result,也是能正常查出来的(,当然,你非要指定也可以)
            @Result(column = "gender", property = "gender", typeHandler = GenderEnumHandler.class),
    })
    Employee select();
    

    相关资料

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值