MyBatis之TypeHandler的自定义实现

ops/2024/10/21 11:26:24/

文章目录

  • 一、TypeHandler概述
  • 二、TypeHandler的工作原理
    • 1.设置参数(Parameter Setting)
    • 2.获取结果(Result Getting)
    • 3.类型映射和转换规则
    • 4.自定义TypeHandler的扩展性
  • 三、自定义的具体实现
    • 业务场景
    • 分析需求
    • 具体实现

一、TypeHandler概述

在 MyBatis 中,类型处理器(TypeHandler)扮演着 JavaType 与 JdbcType 之间转换的桥梁角色。它们用于在执行 SQL 语句时,将 Java 对象的值设置到 PreparedStatement 中,或者从 ResultSet 或 CallableStatement 中取出值。

二、TypeHandler的工作原理

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

1.设置参数(Parameter Setting)

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

具体步骤

  1. MyBatis会根据映射配置找到对应的TypeHandler实例。这个映射配置可以在MyBatis的配置文件或者XML文件中定义。
  2. TypeHandler实例会接收到Java对象中的属性值,并将其转换成JDBC能够识别的类型。这个转换过程是根据Java类型和JDBC类型之间的映射关系来完成的。
  3. 转换后的值会被设置到PreparedStatement对象对应的占位符上,以便数据库能够正常解析和执行SQL语句

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 = "123456789abcdefg".getBytes(StandardCharsets.UTF_8);/*** 设置参数* @param ps SQL 预编译的对象* @param i  需要赋值的索引位置* @param parameter  原本位置i需要赋的值* @param jdbcType   jdbc类型* @throws SQLException*/@Overridepublic 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*/@Overridepublic Encrypt getNullableResult(ResultSet rs, String columnName) throws SQLException {return decrypt(rs.getString(columnName));}/*** 获取值* @param rs     结果集* @param columnIndex       索引* @return* @throws SQLException*/@Overridepublic Encrypt getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return decrypt(rs.getString(columnIndex));}/*** 获取值* @param cs    结果集* @param columnIndex   索引* @return* @throws SQLException*/@Overridepublic 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

http://www.ppmy.cn/ops/123390.html

相关文章

数据结构——排序(交换排序)

目录 一、交换排序的总体概念 二、冒泡排序 三、快速排序 1.挖坑法 2.左右指针 3.前后指针 一、交换排序的总体概念 交换排序是一类排序算法&#xff0c;它的核心思想是通过交换元素的位置来达到排序的目的。在排序过程中&#xff0c;比较数组中的元素对&#xff0c;如果…

RTC -

RTC 目录 RTC 回顾 RTC 如何实现RTC制作一个时钟日历 代码编写 rtc.c完整代码 模块开发的步骤&#xff1a; 1、找文档 2、 在文档里面找通信方式&#xff0c;通信过程&#xff08;协议&#xff09; 3、代码> -- 前面学的是模块的开发&#xff0c;串口类&#xff0c;I…

Expectation-Maximization Algorithm(EM算法)

EM算法&#xff08;Expectation-Maximization Algorithm&#xff0c;期望最大化算法&#xff09;是一种迭代优化算法&#xff0c;主要用于在含有隐变量&#xff08;未观测变量&#xff09;或不完全数据的概率模型中&#xff0c;估计参数的最大似然估计&#xff08;Maximum Like…

初学Java基础Day15---面相对象之this,static关键字,静态代码块

一&#xff0c;this关键字 1.概念&#xff1a; 表示本对象 2.理解&#xff1a; 哪个对象调用该方法&#xff0c;该方法里的this就表示该对象 3.作用&#xff1a; 1.this.属性 &#xff1a; 调用本对象的成员属性 2.this.方法 &#xff1a; 调用本对象的成员方法 3.this() : …

初识JAVA

初识Java 1、Java的优点 跨平台&#xff0c;简单&#xff0c;安全&#xff0c;健壮&#xff0c;面向对象 2、Java的核心优势 跨平台 Java的跨平台原理 1、.class:二进制的&#xff0c;结构中立&#xff0c;平台独立&#xff0c;字节编码文件&#xff1a;bytecode。 2、Java跨…

SeaboxSQL

目录 一、基本架构 0、数据模型 1、主从集群 2、分库分表 二、部署安装 1、配置要求 2、前置依赖 3、安装步骤 三、基本操作 1、实例启停 2、命令执行 3、基本查询 4、表空间管理 4、用户管理 6、数据库操作 7、SCHEMA操作 8、表操作 9、日志操作 &…

【JavaEE】——文件IO

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;认识文件 1&#xff1a;文件的概念 2&#xff1a;文件的结构 3&#xff1a;文件路径…

springboot邮件群发功能的开发与优化策略?

springboot邮件配置指南&#xff1f;如何实现spring邮件功能&#xff1f; SpringBoot框架因其简洁、高效的特点&#xff0c;成为了开发邮件群发功能的理想选择。AokSend将深入探讨SpringBoot邮件群发功能的开发过程&#xff0c;并提出一系列优化策略&#xff0c;以确保邮件发送…