【Mybatis系列】Mybatis之TypeHandler入门

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

  • 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
    • 常用开发工具系列:罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

    • 一.基本介绍
      • 1.什么是 TypeHandler?
      • 2.BaseTypeHandler 使用场景?
      • 3.BaseTypeHandler 常用方法?
    • 二.基础代码
      • 1.启动类
      • 2.创建 handler
      • 3.mapper
    • 三.注解方式
      • 1.注解方式
      • 2.resultMap 配置
      • 3.测试
    • 四.全局配置方式
      • 1.全局配置方式
      • 2.SQL 语句
      • 3.测试用例
    • 五.源码分析
      • 1.BaseTypeHandler
      • 2.setNonNullParameter
      • 3.getNullableResult(接受列名参数)
      • 4.getNullableResult(接受列索引参数)
      • 5.getNullableResult 方法(接受 CallableStatement 参数)
      • 6.类图关系

一.基本介绍

1.什么是 TypeHandler?

“TypeHandler” 通常指的是在软件开发中处理数据类型转换和操作的组件或模块。具体来说,TypeHandler 主要用于将一个数据类型转换为另一个数据类型,以便在不同的上下文中使用。

在不同的编程语言和框架中,TypeHandler 的实现方式可能有所不同。以下是一些常见的情况:

  1. 数据库中的 TypeHandler: 在持久化层,比如与数据库的交互中,TypeHandler 可能用于将数据库中的数据类型与应用程序中的数据类型进行映射。例如,将数据库中的字符串字段映射为应用程序中的整数类型。

  2. Web 开发中的 TypeHandler: 在处理用户输入或从网络传输数据时,可能需要将字符串转换为数字、日期等。TypeHandler 在这种情况下可以用于验证和转换数据类型。

  3. 对象关系映射 (ORM) 中的 TypeHandler: 在使用 ORM 框架时,TypeHandler 通常用于将数据库中的数据类型映射到编程语言中的数据类型。这是因为数据库和编程语言之间可能存在类型差异,需要进行适当的转换。

  4. 用户界面 (UI) 层中的 TypeHandler: 当用户与应用程序的用户界面交互时,输入数据通常以字符串形式提供。TypeHandler 在这里可以用于将用户输入的字符串转换为应用程序内部需要的数据类型。

TypeHandler 在软件开发中扮演着一个数据类型转换和操作的角色,有助于确保不同部分之间的数据一致性和正确性。具体实现方式取决于应用程序的需求和使用的技术栈。

2.BaseTypeHandler 使用场景?

org.apache.ibatis.type.BaseTypeHandler 是 MyBatis 中的一个抽象基类,用于简化自定义类型处理器(TypeHandler)的实现。MyBatis 是一个支持持久化的 Java 持久层框架,而类型处理器用于处理 Java 对象与数据库中的数据类型之间的映射关系。

BaseTypeHandler 提供了一些默认的实现,减少了自定义类型处理器的工作量。

3.BaseTypeHandler 常用方法?

如果你想自定义一个类型处理器,可以继承 BaseTypeHandler 并实现其中的一些方法。以下是 BaseTypeHandler 中的一些关键方法和其作用:

  1. setNonNullParameter 方法:

    • 用于将 Java 类型的非空参数设置到 PreparedStatement 对象中。
    • 子类需要实现此方法以指定如何将 Java 类型的非空参数设置到 PreparedStatement 中。
  2. getNullableResult 方法:

    • 从 ResultSet 中获取指定列的值,以及从 CallableStatement 中获取指定参数的值。
    • 子类需要实现此方法以指定如何从数据库结果集中获取数据。
  3. setNonNullParameter 方法:

    • 将非空的 Java 对象设置到 PreparedStatement 中。
    • 子类需要实现此方法以指定如何将 Java 对象设置到 PreparedStatement 中。
  4. getNullableResult 方法:

    • 从 ResultSet 中获取指定列的值,以及从 CallableStatement 中获取指定参数的值。
    • 子类需要实现此方法以指定如何从数据库结果集中获取数据。

通过继承 BaseTypeHandler,你可以只关注需要自定义的转换逻辑,而无需实现所有的方法。这样,你可以更方便地创建自己的类型处理器,用于处理特定类型的数据映射。

需要注意的是,MyBatis 也提供了一些预定义的类型处理器,用于处理常见的数据类型,如字符串、整数、日期等。但在某些情况下,你可能需要创建自己的类型处理器以处理特定的需求或自定义数据类型。

二.基础代码

1.启动类

@SpringBootApplication
public class AppRun {public static void main(String[] args) {SpringApplication.run(AppRun.class, args);}
}

2.创建 handler

public class Str2DateTypeHandler extends BaseTypeHandler<Date> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, date2Str(parameter));}@Overridepublic Date getNullableResult(ResultSet rs, String columnName) throws SQLException {return str2Date(rs.getString(columnName));}@Overridepublic Date getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return str2Date(rs.getString(columnIndex));}@Overridepublic Date getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return str2Date(cs.getString(columnIndex));}private static Date str2Date(String str) {if (str == null || str.trim().length() == 0) return null;SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");try {return format.parse(str);} catch (Exception e) {throw new RuntimeException(e);}}private static String date2Str(Date date) {if (date == null) return null;SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");try {return format.format(date);} catch (Exception e) {throw new RuntimeException(e);}}
}

3.mapper

@Mapper
public interface TestMapper extends BaseMapper<TestPO> {TestPO selectOne();
}

三.注解方式

1.注解方式

  • autoResultMap:用于自动生成结果映射,而无需手动定义映射关系。
  • typeHandler: 指定类型处理器。
  • @TableName(autoResultMap = true)
  • @TableField(typeHandler = Str2DateTypeHandler.class)
@Data
@TableName(value = "test", autoResultMap = true)
public class TestPO implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.NONE)private String id;@TableField(typeHandler = Str2DateTypeHandler.class)private Date date;
}

2.resultMap 配置

如果返回值是 resultMap 类型,可以通过配置 resultMap 中列的 typeHandler 属性进行类型转换。

<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="org.example.pojo.TestPO"><id column="id" property="id"/><result column="date" property="date" typeHandler="org.example.typehandler.Str2DateTypeHandler"/>
</resultMap>

3.测试

使用 CommandLineRunner 进行测试,方便快捷。

@Component
public class TestRunner implements CommandLineRunner {@Autowiredprivate TestMapper testMapper;@Overridepublic void run(String... args) throws Exception {List<TestPO> list = this.testMapper.selectList(null);System.out.println(list.get(0).getId() + " - " + list.get(0).getDate());}
}

四.全局配置方式

1.全局配置方式

设置类型处理的包路径: type-handlers-package

mybatis-plus:mapper-locations: classpath*:mapper/*Mapper.xmlconfiguration:cache-enabled: truetype-handlers-package: org.example.typehandler

2.SQL 语句

数据库 date 是 String 类型,PO 定义的是 Date 类型,直接查询数据是会报错的。

<select id="selectOne" resultType="org.example.pojo.TestPO">SELECT id, dateFROM test limit 1;
</select>

3.测试用例

使用 CommandLineRunner 进行测试,方便快捷。

@Component
public class TestRunner2 implements CommandLineRunner {@Autowiredprivate TestMapper testMapper;@Overridepublic void run(String... args) throws Exception {TestPO testPO = this.testMapper.selectOne();System.out.println(testPO.getId() + " - " + testPO.getDate());}
}

五.源码分析

1.BaseTypeHandler

需要重写的四个方法如下:

public abstract void setNonNullParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException;public abstract T getNullableResult(ResultSet var1, String var2) throws SQLException;public abstract T getNullableResult(ResultSet var1, int var2) throws SQLException;public abstract T getNullableResult(CallableStatement var1, int var2) throws SQLException;

2.setNonNullParameter

作用: 该方法用于将 Java 类型的非空参数设置到 PreparedStatement 对象中,以便将数据插入到数据库中。

参数:

  • var1:表示要设置参数的 PreparedStatement 对象。
  • var2:表示要设置的参数的位置。
  • var3:表示要设置的非空参数值,即从 Java 对象映射到数据库中的数据。
  • var4:表示 JDBC 类型,用于指定参数的数据类型。

异常: 抛出 SQLException,以处理可能的数据库操作异常。

3.getNullableResult(接受列名参数)

作用: 该方法从 ResultSet 中获取指定列的值,并将其映射为 Java 对象,处理可空的查询结果。

参数:

  • var1:表示要获取数据的 ResultSet 对象。
  • var2:表示要获取的列的名称。

返回值: 返回映射到 Java 对象的可空结果。

异常: 抛出 SQLException,以处理可能的数据库操作异常。

4.getNullableResult(接受列索引参数)

作用: 该方法从 ResultSet 中获取指定列的值,并将其映射为 Java 对象,处理可空的查询结果。

参数:

  • var1:表示要获取数据的 ResultSet 对象。
  • var2:表示要获取的列的索引。

返回值: 返回映射到 Java 对象的可空结果。

异常: 抛出 SQLException,以处理可能的数据库操作异常。

5.getNullableResult 方法(接受 CallableStatement 参数)

作用: 该方法从 CallableStatement 中获取指定位置的值,并将其映射为 Java 对象,处理可空的查询结果。

参数:

  • var1:表示要获取数据的 CallableStatement 对象。
  • var2:表示要获取的位置。

返回值: 返回映射到 Java 对象的可空结果。

异常: 抛出 SQLException,以处理可能的数据库操作异常。

6.类图关系

image-20231128122432039

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/225010.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

助力企业实现更简单的数据库管理,ATOMDB 与 TDengine 完成兼容性互认

为加速数字化转型进程&#xff0c;当下越来越多的企业开始进行新一轮数据架构改造升级。在此过程中&#xff0c;全平台数据库管理客户端提供了一个集中管理和操作数据库的工具&#xff0c;提高了数据库管理的效率和便利性&#xff0c;减少了人工操作的复杂性和错误率&#xff0…

统信UOS_麒麟KYLINOS上使用远程SSH连接的工具electerm

原文链接&#xff1a;统信UOS/麒麟KYLINOS上使用SSH工具electerm Hello&#xff0c;大家好啊&#xff01;在我们日常的工作和学习中&#xff0c;远程控制和管理服务器已经成为一项常见且必要的技能。尤其是对于IT专业人士和开发者来说&#xff0c;一个高效、稳定的远程SSH连接工…

AI 绘画 | Stable Diffusion 提示词扩展插件

前言 提示词对于Stable Diffusion AI绘画来说非常重要, 由于Stable Diffusion 支持英文提示词,对于英文不好的朋友,每次都要切换翻译网站去翻译,很不方便,下面介绍两款Stable Diffusion 提示词扩展插件,让你写提示词更轻松。 sd-webui-prompt-all-in-one 提示词多合一插…

yolov8-pose 推理流程

目录 一、关键点预测 二、图像预处理 二、推理 三、后处理与可视化 3.1、后处理 3.2、特征点可视化 四、完整pytorch代码 yolov8-pose tensorrt 一、关键点预测 注&#xff1a;本篇只是阐述推理流程&#xff0c;tensorrt实现后续跟进。 yolov8-pose的tensorrt部署代码…

CH02_交给子类

Template Method模式 组成模板的方法被定义在父类中&#xff0c;由于这些方法是抽象方法&#xff0c;所以只查看父类的代码是无法知道这些方法最终会进行何种具体处理的。唯一能知道的就是父类如何调用这些方法。 类图 说明 AbstractClass&#xff08;抽象类&#xff09; Abs…

Vue路由跳转页面刷新

案例使用映射路由 百度的时候各种操作就是没有注意keepAlive&#xff0c;发现那个为缓存开启之后前端有个小后台Vue生命周期函数失效。同一个页面刷新时这个keep Alive需要关闭。

二十章多线程

概念 有很多工作是可以同时完成的&#xff0c;这种思想放在Java中被称为并发&#xff0c;并发完成每一件事被称为线程。 程序员可以在程序中执行多个线程&#xff0c;每一个线程完成一个功能//与其他线程并发执行&#xff0c;这种机制被称为多线程&#xff0c;并不算所有编程…

10.索引

一.索引简介 索引用于快速找出在某个列中有一特定值的行。 不使用索引&#xff0c;MySQL必须从第1条记录开始读完整个表&#xff0c;直到找出相关的行。表越大&#xff0c;查询数据所花费的时间越多。 如果表中查询的列有一个索引&#xff0c;MySQL能快速到达某个位置去搜寻…

鞋厂ERP怎么样?工厂要如何选项契合的ERP

鞋帽这类商品是我们的生活必需品&#xff0c;存在款式多、尺码多、用料复杂、营销渠道多、销售策略和价格策略灵活等情况&#xff0c;伴随电商等行业的发展&#xff0c;鞋帽行业的管理模式也在发生变化。 鞋厂规模的不同&#xff0c;遇到的管理问题各异&#xff0c;而如何解决…

[英语学习][3][Word Power Made Easy]的精读与翻译优化

[序言] 这次翻译校验, 难度有点大, 原版中英翻译已出现了严重地偏差. 昨晚11点开始阅读如下段落, 花费了1个小时也没有理解原作者的核心表达, 索性睡觉了. 今早学习完朗文单词之后, 9点半开始继续揣摩. 竟然弄到了中午11点30, 终于明白原作者要表达的意思了. 废话不多说&#x…

「Verilog学习笔记」非整数倍数据位宽转换8to12

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 要实现8bit数据至12bit数据的位宽转换&#xff0c;必须要用寄存器将先到达的数据进行缓存。8bit数据至12bit数据&#xff0c;相当于1.5个输入数据拼接成一个输出数据&#…

Find My电容笔|苹果Find My技术与电容笔结合,智能防丢,全球定位

随着平板电脑的流行&#xff0c;有不少厂商都投入到了电容笔的开发当中&#xff0c;现在的电容笔不仅在精度上有了提高&#xff0c;甚至在笔触和压感上的研究都有进步。电容笔是利用导体材料制作的具有导电特性、用来触控电容式屏幕完成人机对话操作用的笔&#xff0c;电容笔通…