mybatisplus中配置TypeHanlder实现自定义转换

1 TypeHandler的使用场景

在我们的项目中,可能会涉及到状态类型的枚举到数据库字段的映射转换,此时就需要使用TypeHandler,
在这里插入图片描述
对应数据库支付表中pay_type字段,这里就需要定义一个类型转换TypeHandler,来把枚举中的code映射到数据库中

2 TypeHandler原理

无论是用Spring DataJpa, Hibernate,Mybatis 或者Mybatis-plus,其最终都是使用的Jdbc,而Jdbc操作数据需要模板式的7步操作,在使用Mybatis #{} 占位符式设置值的时候,使用的就是PreparedStatement对象,通过占位符的下标位置,以及对应Value进行赋值,在查询的时候,返回的结果集为ResultSet,通过指针的方式,get出来获取到指定行
,

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

public interface TypeHandler<T> {
	
    /**
    * java属性->数据库字段映射  占位符赋值操作
    */
    void setParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException;
    
    /**
    * 下面3个方法 都是数据库字段->java属性 数据库字段映射java属性操作
    */
	 
    T getResult(ResultSet var1, String var2) throws SQLException;

    T getResult(ResultSet var1, int var2) throws SQLException;

    T getResult(CallableStatement var1, int var2) throws SQLException;
}

3 自定义TypeHandler使用

mybatis中抽象类BaseTypeHandler已经实现了TypleHandler接口,我们直接继承它就好

public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> {....}

4 实现LocalDateTime的TypeHanlder转换

自定义TypeHandler,添加泛型为LocalDateTime

@MappedJdbcTypes(JdbcType.VARCHAR) // 数据库中该字段存储的类型
@MappedTypes(LocalDateTime.class) // 需要转换的对象
public class MyLocalDateTimeTypeHanlder extends BaseTypeHandler<LocalDateTime> {

    private static DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");  
    
	/*
	* java属性 - > db属性   
	*/
	
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime localDateTime, JdbcType jdbcType) throws SQLException {
        // 这里需要把LocalDateTime格式化成标准的数据格式,否则数据库中字段属性为varchar而不是datetime,则会出现毫秒后面多出几位的情况
        String formatStr = localDateTime.format(df);
        // 这里setObject的原因是 ps.setXXX()只有常见的基本类型,LocalDateTime不属于其中,故需setObject
        ps.setObject(i, formatStr);
    }
    
	/*
	* 如下3个方法都是 db - > java  即查询出来的数据 -> java属性映射
	*/
	
    @Override
    public LocalDateTime getNullableResult(ResultSet resultSet, String s) throws SQLException {
        // 返回的时候也需要格式化,变成标准格式
        LocalDateTime localDateTime = LocalDateTime.parse(s, df);
        return localDateTime;
    }
    
    @Override
    public LocalDateTime getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return resultSet.getObject(i,LocalDateTime.class);
    }

    @Override
    public LocalDateTime getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return callableStatement.getObject(i, LocalDateTime.class);
    }
}

5 实际应用,只需要在对应的注解上加上即可

在这里插入图片描述

如下图,当数据库createTime为varchar类型时
在这里插入图片描述
没有转换之前(第一个行)和转换后的效果如下,使用自定义TypeHandler后,转换后正常,为标准的的:yyyy-MM-dd HH:mm:ss格式
在这里插入图片描述

6 实现普通枚举的TypeHanlder转换

public enum PayTypeEnum {

    //
    WECHAT(1, "微信"),
    ALIPAY(2, "支付宝"),
    UNION(3, "银联"),
    ;

    private Integer code;

    private String msg;

    PayTypeEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer code() {
        return code;
    }

    public String msg() {
        return msg;
    }

    public static PayTypeEnum parse(Integer code) {
        for (PayTypeEnum value : values()) {
            if (value.code.equals(code)) {
                return value;
            }
        }
        return null;
    }

}

定义该枚举的TypeHandler

@MappedJdbcTypes(JdbcType.INTEGER)
@MappedTypes(PayTypeEnum.class)
public class MyEnumTypeHanlder extends BaseTypeHandler<PayTypeEnum> {


    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, PayTypeEnum payTypeEnum, JdbcType jdbcType) throws SQLException {
        // 枚举code对应的数据库字段类型
        preparedStatement.setInt(i,PayTypeEnum.code());
    }

    @Override
    public PayTypeEnum getNullableResult(ResultSet resultSet, String columName) throws SQLException {
        // 根据字段名获取枚举code值
        int code = resultSet.getInt(columName);
        PayTypeEnum instance = PayTypeEnum.parse(code);
        return instance;
    }

    @Override
    public PayTypeEnum getNullableResult(ResultSet resultSet, int columIndex) throws SQLException {
        int code = resultSet.getInt(columIndex);
        PayTypeEnum instance = PayTypeEnum.parse(code);
        return instance;
    }

    @Override
    public PayTypeEnum getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return null;
    }
}

7 所用依赖

<dependency>
  <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-boot-starter</artifactId>
   <version>3.1.0</version>
</dependency>

8 配置扫包

如果为mybatis-plus 则在yml文件中加入如下配置:

#  mybatis-plus 配置 typeHandler
mybatis-plus:
  type-handlers-package: 你的自定义typeHandler所在包

如果为mybatis 则去掉前缀中 -plus即可

  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值