当前位置: 首页 > news >正文

【Mybatis】TypeHandler使用

引言

在使用MyBatis进行项目开发时,我们经常会遇到Java类型与数据库类型不匹配的情况。为了解决这一问题,MyBatis提供了一个强大的机制——TypeHandlerTypeHandler是MyBatis中一个用于处理Java类型和数据库类型转换的组件,它在MyBatis进行参数设置和结果映射时起着至关重要的作用。本文将详细介绍TypeHandler的使用方法,包括自定义TypeHandler的创建和注册,以及在实际项目中的应用示例。

TypeHandler基础

什么是TypeHandler

在MyBatis中,TypeHandler用于处理Java类型和JDBC类型之间的映射和转换。每当MyBatis在执行SQL操作时,都会使用TypeHandler来确保数据类型的正确转换。

TypeHandler的工作原理

当MyBatis从数据库读取数据时,TypeHandler负责将数据库类型转换为Java类型;反之,当MyBatis向数据库写入数据时,它将Java类型转换为数据库类型。这一过程对于开发者是透明的,由MyBatis框架内部自动完成。

TypeHandler的应用

内置TypeHandler

MyBatis已经为我们提供了一系列内置的TypeHandler,用于处理常见的Java类型与数据库类型之间的转换。例如,IntegerTypeHandlerStringTypeHandler等。

自定义TypeHandler

尽管MyBatis提供了很多内置的TypeHandler,但在某些特殊情况下,我们可能需要自定义TypeHandler来处理特定的类型转换。自定义TypeHandler可以让我们控制复杂类型的持久化策略,例如枚举类型、复杂的对象类型等。

创建自定义TypeHandler

创建一个自定义的TypeHandler首先需要实现MyBatis的TypeHandler接口或者继承BaseTypeHandler类。以下是一个简单的自定义TypeHandler示例,用于转换枚举类型:

public enum EnumType {ACTIVE("A"),DISABLED("D"),DELETED("X");private final String code;EnumType(String code) {this.code = code;}public String getCode() {return code;}public static EnumType fromCode(String code) {for (EnumType status : EnumType.values()) {if (status.getCode().equals(code)) {return status;}}throw new IllegalArgumentException("Unknown code: " + code);}
}
public class MyEnumTypeHandler extends BaseTypeHandler<EnumType> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, EnumType parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, parameter.getCode());}@Overridepublic EnumType getNullableResult(ResultSet rs, String columnName) throws SQLException {String code = rs.getString(columnName);return EnumType.fromCode(code);}@Overridepublic EnumType getNullableResult(ResultSet rs, int columnIndex) throws SQLException {String code = rs.getString(columnIndex);return EnumType.fromCode(code);}@Overridepublic EnumType getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {String code = cs.getString(columnIndex);return EnumType.fromCode(code);}
}

在上述代码中,EnumType是一个枚举类型,我们通过覆写BaseTypeHandler的方法来实现自定义的类型转换逻辑。

注册自定义TypeHandler

自定义的TypeHandler创建完成后,需要在MyBatis配置文件中进行注册才能使用。可以通过以下两种方式注册自定义TypeHandler

  • 在MyBatis全局配置文件mybatis-config.xml中注册:
<typeHandlers><typeHandler handler="com.example.MyEnumTypeHandler"/>
</typeHandlers>
  • 使用注解直接在Mapper方法上指定使用的TypeHandler
@Select("SELECT * FROM some_table WHERE column = #{enumValue,typeHandler=com.example.MyEnumTypeHandler}")
SomeObject selectByEnumValue(EnumType enumValue);

实际应用示例

接下来,我们将通过一个实际的示例来展示如何在项目中应用自定义TypeHandler

假设我们有一个用户表(user),其中有一个枚举类型的字段用于表示用户状态(status)。我们可以使用上面创建的MyEnumTypeHandler来处理这个字段的读写操作。

public class User {private Integer id;private String name;private String email;private EnumType status; // 使用EnumType枚举表示用户状态// 构造函数public User() {}// Getter和Setter方法public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public EnumType getStatus() {return status;}public void setStatus(EnumType status) {this.status = status;}// 有toString()、equals()和hashCode()方法
}

Mapper接口

public interface UserMapper {@Select("SELECT * FROM user WHERE id = #{id}")@Results({@Result(property = "status", column = "status", typeHandler = MyEnumTypeHandler.class)})User selectById(int id);@Insert("INSERT INTO user(name, status) VALUES(#{name}, #{status, typeHandler=com.example.MyEnumTypeHandler})")void insertUser(User user);
}

使用TypeHandler进行查询和插入

使用UserMapper接口,我们可以很容易地插入和查询具有枚举类型字段的用户记录。

User user = new User();
user.setName("Alice");
user.setStatus(EnumType.ACTIVE);
userMapper.insertUser(user);User dbUser = userMapper.selectById(user.getId());
System.out.println(dbUser.getStatus()); // 输出 ACTIVE

通过上述示例,我们可以看到自定义TypeHandler在处理枚举类型字段时的强大功能和灵活性。

TypeHandler接口

TypeHandler接口定义在org.apache.ibatis.type包中,它定义了几个核心的方法,这些方法用于将Java类型转换为JDBC类型,以及将JDBC类型转换回Java类型。以下是TypeHandler接口的一个基本概述:

public interface TypeHandler<T> {void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;T getResult(ResultSet rs, String columnName) throws SQLException;T getResult(ResultSet rs, int columnIndex) throws SQLException;T getResult(CallableStatement cs, int columnIndex) throws SQLException;}
  • setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType): 该方法用于在PreparedStatement中设置参数。它将Java类型转换为一个可以在SQL查询中使用的JDBC类型。
  • getResult(ResultSet rs, String columnName): 从ResultSet中获取名为columnName的列的值,并将其转换为Java类型。
  • getResult(ResultSet rs, int columnIndex): 从ResultSet中获取指定列索引的值,并将其转换为Java类型。
  • getResult(CallableStatement cs, int columnIndex): 从CallableStatement中获取指定列索引的值,并将其转换为Java类型。

BaseTypeHandler抽象类

BaseTypeHandlerTypeHandler接口的一个抽象实现,提供了一些实用的方法简化了自定义TypeHandler的开发。大多数自定义TypeHandler都会继承这个类,因为它实现了TypeHandler接口的大部分通用逻辑,让开发者只需关注于特定类型转换的实现。BaseTypeHandler提供的一些方法包括:

public abstract class BaseTypeHandler<T> implements TypeHandler<T> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {// 实现类需要覆盖这个方法来设置非空参数}@Overridepublic T getNullableResult(ResultSet rs, String columnName) throws SQLException {// 实现类需要覆盖这个方法来获取可能为空的结果}@Overridepublic T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {// 实现类需要覆盖这个方法来获取可能为空的结果}@Overridepublic T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {// 实现类需要覆盖这个方法来获取可能为空的结果}}

我们实现自定义TypeHandler时,通常会继承BaseTypeHandler类,并实现上述的setNonNullParametergetNullableResult方法来处理具体的类型转换逻辑。

结语

MyBatis的TypeHandler是一个强大的机制,它为我们提供了一种灵活的方式来处理Java类型与数据库类型之间的转换。通过使用内置的TypeHandler或创建自定义的TypeHandler,我们可以轻松地解决在实际开发中遇到的类型不匹配问题。希望本文能够帮助读者更好地理解和使用MyBatis中的TypeHandler

相关文章:

【Mybatis】TypeHandler使用

引言 在使用MyBatis进行项目开发时&#xff0c;我们经常会遇到Java类型与数据库类型不匹配的情况。为了解决这一问题&#xff0c;MyBatis提供了一个强大的机制——TypeHandler。TypeHandler是MyBatis中一个用于处理Java类型和数据库类型转换的组件&#xff0c;它在MyBatis进行…...

[计算机网络]---网络编程套接字

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、基础知识…...

分布式文件系统 SpringBoot+FastDFS+Vue.js【二】

分布式文件系统 SpringBootFastDFSVue.js【二】 六、实现上传功能并展示数据6.1.创建数据库6.2.创建spring boot项目fastDFS-java6.3.引入依赖6.3.fastdfs-client配置文件6.4.跨域配置GlobalCrosConfig.java6.5.创建模型--实体类6.5.1.FastDfsFile.java6.5.2.FastDfsFileType.j…...

开源软件:推动软件行业繁荣的力量

文章目录 &#x1f4d1;引言开源软件的优势分析开放性与透明度低成本与灵活性创新与协作 开源软件对软件行业的影响推动技术创新和进步促进软件行业的合作与交流培养人才和提高技能促进软件行业的可持续发展 结语 &#x1f4d1;引言 随着信息技术的飞速发展&#xff0c;软件已经…...

[杂记]mmdetection3.x中的数据流与基本流程详解(数据集读取, 数据增强, 训练)

之前跑了一下mmdetection 3.x自带的一些算法, 但是具体的代码细节总是看了就忘, 所以想做一些笔记, 方便初学者参考. 其实比较不能忍的是, 官网的文档还是空的… 这次想写其中的数据流是如何运作的, 包括从读取数据集的样本与真值, 到数据增强, 再到模型的forward当中. 0. MMDe…...

阿里云香港轻量应用服务器怎么样,建站速度快吗?

阿里云香港服务器中国香港数据中心网络线路类型BGP多线精品&#xff0c;中国电信CN2高速网络高质量、大规格BGP带宽&#xff0c;运营商精品公网直连中国内地&#xff0c;时延更低&#xff0c;优化海外回中国内地流量的公网线路&#xff0c;可以提高国际业务访问质量。阿里云服务…...

事务及在SpringBoot项目中使用的两种方式

1.事务简介 事务&#xff08;transaction&#xff09;是访问并可能操作各种数据项的一个数据库操作序列&#xff0c;这些操作要么全部执行&#xff0c;要么全部不执行&#xff0c;是一个不可分割的工作单位。 事物的四大特性: 原子性&#xff08;Atomicity&#xff09;&#xf…...

stm32--笔记

一、引脚与变量 ​​​​​​​​​​​​​​ 二、STM32时钟 [STM32-时钟系统详解_stm32时钟_KevinFlyn的博客-CSDN博客] 三、定时器中断实验 1、定时器中断实验 ​ stm32关于通用定时器的周期、频率计算公式_stm32tim频率计算_胶囊咖啡的博客-CSDN博客 ​ 【STM32】通用…...

2024前端面试准备之CSS篇(二)

全文链接 1. 什么是伪类和伪元素 伪类(Pseudo-class): 伪类是选择器的一种,用于选择特定状态或条件下的元素。它们以冒号(:)开头,用于向选择器添加额外的特定条件。例如,:hover伪类用于选择鼠标悬停在元素上的状态,:nth-child(n)伪类用于选择父元素下的第n个子元素等。…...

轨道交通信号增强与覆盖解决方案——经济高效,灵活应用于各类轨道交通场景!

方案背景 我国是世界上轨道交通里程最长的国家&#xff0c;轨道交通也为我们的日常出行带来极大的便利。伴随着无线通信技术的快速发展将我们带入电子时代&#xff0c;出行的过程中对无线通信的依赖程度越来越高&#xff0c;无论是车站还是车内都需要强大、高质量的解决方案以…...

学习数据接构和算法的第10天

题目讲解 尾插 #include <stdio.h> #include <stdlib.h> // 定义顺序表结构 #define MAX_SIZE 100 struct ArrayList {int array[MAX_SIZE];int size; // 当前元素个数 }; // 初始化顺序表 void init(struct ArrayList *list) {list->size 0; // 初始时元素个…...

初识KMP算法

目录 1.KMP算法的介绍 2.next数组 3.总结 1.KMP算法的介绍 首先我们会疑惑&#xff0c;什么是KMP算法&#xff1f;这个算法是用来干什么的&#xff1f; KMP&#xff08;Knuth-Morris-Pratt&#xff09;算法是一种用于字符串匹配的经典算法&#xff0c;它的目标是在一个主文本…...

Javaweb之SpringBootWeb案例之AOP概述及入门的详细解析

2.1 AOP概述 什么是AOP&#xff1f; AOP英文全称&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程、面向方面编程&#xff09;&#xff0c;其实说白了&#xff0c;面向切面编程就是面向特定方法编程。 那什么又是面向方法编程呢&#xff0c;为什么又需要面向…...

【Java代码洁癖】NO.2 单元测试mock显式赋值,不能忍

反例 RunWith(MockitoJunitRunner.class) public class Test {Mockpublic SomeBean someBean new SomeBean(); } 正例 RunWith(MockitoJunitRunner.class) public class Test {Mockpublic SomeBean someBean ; } 解读 使用Mock注解的对象不应该被显式赋值&#xff0c;应当…...

2024.2.19

使用fread和fwrite完成两个文件的拷贝 #include<stdio.h> #include<stdlib.h> #include<string.h> int main(int argc, const char *argv[]) {FILE *fpNULL;if((fpfopen("./tset.txt","w"))NULL){perror("open error");retur…...

B端系统升级方案模板:针对美观性和体验性升级(总体方案)

大家好&#xff0c;我是大美B端工场&#xff0c;专注于前端开发和UI设计&#xff0c;有需求可以私信。本篇从全局分享如何升级B端系统&#xff0c;搞B端系统升级的有个整体思维&#xff0c;不是说美化几个图标&#xff0c;修改几个页面就能解决的&#xff0c;这个方案模板&…...

第九篇:node静态文件服务(中间件)

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! &#x1f4d8; 引言&#xff1a; 当今互联网时代&am…...

软件测试-功能测试-测试流程-如何进行需求评审?对于测试人员来讲,如何从测试的角度评审需求文档?

导言 产品人员编写的需求文档&#xff0c;无疑是一个项目或者一项新功能的开端。需求文档的优劣&#xff0c;直接影响开发人员的代码质量&#xff0c;更会影响到后续的测试工作。所以&#xff0c;我认为&#xff0c;需求评审对于开发质量以及测试质量至关重要&#xff0c;那么…...

无刷电机驱动详解

无刷电机驱动详解 有刷电机和无刷电机字面上理解最大的区别就是有无电刷&#xff0c;实际上区别还有换向器&#xff0c;电刷和换向器的作用是什么&#xff1f;电刷负责在旋转部件与静止部件之间传导电流&#xff0c;换向器则利用旋转惯性周期性的改变线圈中电流的方向。 所以…...

Linux+Win双系统远程重启到Win

背景 电脑安装了双系统&#xff08;ubuntu 22.04 win11&#xff09;&#xff0c;默认进入ubuntu系统。给电脑设置了WoL(Wake-on-LAN)&#xff0c;方便远程开机远程控制。 但是ubuntu的引导程序grub无法远程控制&#xff0c;远程开机会默认进入ubuntu。 虽然说可以进入ubuntu后…...

数据主权时代,企业即时通讯厂商选型推荐

BeeWorks作为企业级私有化 IM&#xff0c;主打安全可控、深度协同、信创适配&#xff0c;在政企、军工、金融等强合规场景口碑突出。BeeWorks 定位为安全专属数字化协作平台&#xff0c;核心是私有化部署 全链路安全 业务深度融合&#xff0c;区别于通用 SaaS IM。1. 核心架构…...

告别单调模型!FreeCAD‘逐面着色’保姆级教程:从颜色理论到3D打印预览

告别单调模型&#xff01;FreeCAD‘逐面着色’保姆级教程&#xff1a;从颜色理论到3D打印预览 在3D设计领域&#xff0c;模型的美观度往往决定了第一印象。你是否遇到过这样的困境&#xff1a;精心建模的作品因为单调的色彩而失去表现力&#xff1f;FreeCAD的逐面着色功能正是打…...

别再死记硬背了!用74HC系列CMOS芯片,手把手带你理解逻辑门电平与噪声容限

74HC系列CMOS芯片实战&#xff1a;从数据手册到面包板的逻辑门电平全解析 当你在深夜调试一块74HC04反相器搭建的振荡电路时&#xff0c;示波器上本该清晰的方波却出现了毛刺和畸变——这种场景对电子爱好者来说再熟悉不过。本文将以74HC系列CMOS芯片为核心&#xff0c;通过五…...

猫抓插件:资源嗅探技术如何重塑浏览器媒体捕获体验

猫抓插件&#xff1a;资源嗅探技术如何重塑浏览器媒体捕获体验 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 在数字内容爆炸的时代&#xff0c;网…...

掌握 Skills 技术引爆 Agent 开发!像装 App 一样让 AI 变“超人”!

本文介绍了 AI Skills 的概念&#xff0c;将其描述为可像人类一样动态加载和使用的“能力模块”&#xff0c;用于解决传统 Agent 开发的痛点&#xff0c;如重复造轮子、能力边界模糊和难以规模化。文章详细阐述了 Skills 的核心特征&#xff08;模块化、可组合、热插拔、标准化…...

3步掌握DDrawCompat:轻松解决Windows老游戏兼容性的终极方案

3步掌握DDrawCompat&#xff1a;轻松解决Windows老游戏兼容性的终极方案 【免费下载链接】DDrawCompat DirectDraw and Direct3D 1-7 compatibility, performance and visual enhancements for Windows Vista, 7, 8, 10 and 11 项目地址: https://gitcode.com/gh_mirrors/dd/…...

3个核心技巧:快速掌握免费在线PPT编辑器PPTist的创作秘诀

3个核心技巧&#xff1a;快速掌握免费在线PPT编辑器PPTist的创作秘诀 【免费下载链接】PPTist PowerPoint-ist&#xff08;/pauəpɔintist/&#xff09;, An online presentation application that replicates most of the commonly used features of MS PowerPoint, allowing…...

BilibiliDown:让B站视频下载变得简单高效

BilibiliDown&#xff1a;让B站视频下载变得简单高效 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mirrors/bi/BilibiliDo…...

linux https拦截与url解析

uprobe 拦截TLS库 用 eBPF uprobe 拦截 TLS 库&#xff08;OpenSSL/GnuTLS/Go TLS&#xff09;&#xff0c;在加密前 / 解密后捕获明文 HTTP 请求&#xff0c;即可解析出 HTTPS URL&#xff0c;无需 CA 证书、无需修改应用。 核心原理 HTTPS 明文&#xff08;含 URL&#xf…...

机器标识重置技术实现的Cursor Pro功能解锁解决方案

机器标识重置技术实现的Cursor Pro功能解锁解决方案 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youve reached your trial request li…...