您好,欢迎来到刀刀网。
搜索
您的当前位置:首页MyBatis之TypeHandler的自定义实现

MyBatis之TypeHandler的自定义实现

来源:刀刀网

一、TypeHandler概述

二、TypeHandler的工作原理

TypeHandler在MyBatis中是一个核心概念,其工作原理主要涉及Java类型和JDBC类型之间的转换。下面将详细介绍TypeHandler的工作原理。

1.设置参数(Parameter Setting)

当Mybatis要执行一个sql语句时,(例如INSERT UPDATE等),它需要将Java对象的属性值设置到SQL语句对应的占位符上,这个过程就是通过TypeHandler来完成的。

具体步骤

2.获取结果(Result Getting)

当数据库进行查询操作并返回结果集合时,MyBatis需要将结果集中的数据提取出来,转换成Java对象中的对应属性类型,这个过程同样是由TypeHandler来完成的。

具体步骤

  1. MyBatis会根据映射配置找到对应的TypeHandler实例
  2. TypeHandler实例会从ResultSet对象中提取数据,这个提取过程是根据数据库字段和Java属性之间的映射关系来实现的。
  3. 提取出来的数据会被转换成Java对象中的对应属性类型,这个转换过程是由Java类型和JDBC类型之间的映射关系来完成的。
  4. 转换后的值会被设置到Java对象中对应的属性上,以便程序能够正确处理和使用这些数据。

3.类型映射和转换规则

TypeHandler的核心功能是实现Java类型和JDBC类型之间的映射和转换。这个映射和转换规则是根据Java类型和JDBC类型的特性和语义来定义的。

对于基本数据类型(如int、long、float等),MyBatis提供了内置的TypeHandler实现,这些实现能够直接将Java基本数据类型转换为对应的JDBC基本数据类型,反之亦然。
对于复杂数据类型(如自定义对象、集合等),MyBatis允许开发者自定义TypeHandler来实现复杂的类型转换逻辑。

4.自定义TypeHandler的扩展性

MyBatis的TypeHandler机制具有很高的扩展性。我们可以通过实现TypeHandler接口或继承BaseTypeHandler类来创建自定义的TypeHandler实现。自定义的TypeHandler可以实现任意复杂的类型转换逻辑,以满足特定业务需求。

此外,MyBatis还提供了丰富的API和扩展点来支持开发者自定义TypeHandler的注册和使用方式。我们可以通过配置文件、注解或编程方式将自定义的TypeHandler注册到MyBatis中,并在Mapper的XML映射文件中引用它们来处理特定的数据类型转换需求。

三、自定义的具体实现

业务场景

现在我们要对用户存入的手机号进行处理。存入手机号时需要进行加密操作,从数据库中取出手机号时,进行解密。

分析需求

TypeHandler是将指定类型转换成数据库支持的类型

  1. TypeHandler拿到手机号,进行加密
  2. TypeHandler加密后转换成指定JDBC类型存入数据库
  3. TypeHandler从数据库中取出JDBC类型
  4. TypeHandler拿到JDBC类型进行解密
  5. 返回手机号

具体实现

我们先定义一个Encrypt类。
这是我们自定义的类,后续会配合注解使用。

@Data
public class Encrypt {

    private String value;
    public Encrypt(){}
    public Encrypt(String value){
        this.value = value;
    }
}
@MappedTypes(Encrypt.class)     //被处理的类型
@MappedJdbcTypes(JdbcType.VARCHAR)      //转换成的JDBC类型
public class EncryptTypeHandler extends BaseTypeHandler<Encrypt> {

    //手机号的加密我们采用aes加密方式
    //密钥
    private final byte[] KEY = "1234567abcdefg".getBytes(StandardCharsets.UTF_8);

    /**
     * 设置参数
     * @param ps SQL 预编译的对象
     * @param i  需要赋值的索引位置
     * @param parameter  原本位置i需要赋的值
     * @param jdbcType   jdbc类型
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Encrypt parameter, JdbcType jdbcType) throws SQLException {
            if(parameter == null || parameter.getValue() == null){
                ps.setString(i,null);
                return;
            }
            AES aes = new AES(KEY);
            String str = aes.encryptHex(parameter.getValue());
            ps.setString(i, str);
    }

    /**
     * 获取值
     * @param rs    结果集
     * @param columnName       索引名
     * @return
     * @throws SQLException
     */
    @Override
    public Encrypt getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return decrypt(rs.getString(columnName));
    }

    /**
     * 获取值
     * @param rs     结果集
     * @param columnIndex       索引
     * @return
     * @throws SQLException
     */
    @Override
    public Encrypt getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return decrypt(rs.getString(columnIndex));
    }

    /**
     * 获取值
     * @param cs    结果集
     * @param columnIndex   索引
     * @return
     * @throws SQLException
     */
    @Override
    public Encrypt getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return decrypt(cs.getString(columnIndex));
    }

	//解密方法
    private Encrypt decrypt(String str){
        if (StringUtils.hasText(str)){
            return null;
        }
        return new Encrypt(SecureUtil.aes(KEY).decryptStr(str));
    }
}

注意
在properties文件中配置路径

mybatis.type-handlers-package=com.example.lottery.dao.handler

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- gamedaodao.com 版权所有 湘ICP备2022005869号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务