MyBatis TypeHandler 详解与实战:FastJson 实现字符串转 List

在 MyBatis 中,TypeHandler 是实现 Java 类型与数据库类型双向转换 的核心组件。无论是处理基础数据类型还是复杂的 JSON、枚举或自定义对象,它都能通过灵活的扩展机制满足开发需求。本文将通过一个 将数据库 JSON 字符串转换为 List<User> 的案例,详解 TypeHandler 的原理与实践。


一、TypeHandler 的作用与原理

1. 核心功能

  • 类型转换桥梁:将 Java 对象属性转换为 JDBC 参数(如 PreparedStatement 设置值);
  • 结果集映射:将数据库查询结果(如 ResultSet)转换为 Java 对象属性;
  • 空值处理:统一处理 Java 对象与数据库字段的 NULL 值逻辑。

2. 应用场景

  • 内置类型处理:MyBatis 已支持 StringIntegerDate 等常见类型的转换;
  • 复杂类型处理:如 JSON 字符串与对象互转、枚举值与数据库标记映射、CSV 字符串与集合转换等。

二、TypeHandler 的配置与扩展

1. 内置 TypeHandler

MyBatis 默认提供多种 TypeHandler,例如:

  • StringTypeHandler:处理 VARCHARString
  • EnumTypeHandler:处理枚举与数据库标记(如 disabled0);
  • DateTypeHandler:处理日期类型与 TIMESTAMP 的转换。

2. 自定义 TypeHandler 步骤

  1. 继承 BaseTypeHandler:实现 setNonNullParameter(Java→JDBC)和 getNullableResult(JDBC→Java)方法;
  2. 注册处理器
    • 全局注册:在 mybatis-config.xml 中通过 <typeHandlers> 标签配置;
    • 局部指定:在 Mapper XML 或注解中通过 typeHandler 属性标记;
  3. 应用转换逻辑:在实体类字段或 SQL 映射中声明使用自定义 TypeHandler。

三、实战:FastJson 实现 JSON 字符串与 List 转换

1. 场景描述

假设数据库表 user_groupusers 字段存储 JSON 字符串,需在 Java 中映射为 List<User> 对象:

CREATE TABLE user_group (
    id BIGINT PRIMARY KEY,
    users VARCHAR(2048)  -- 存储格式:[{"id":1,"name":"Alice","age":25},...]
);

2. 实现步骤

① 引入依赖
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version>
</dependency>
② 定义 User 实体
public class User {
    private Long id;
    private String name;
    private Integer age;
    // getters/setters
}
③ 自定义 TypeHandler
public class ListUserTypeHandler extends BaseTypeHandler<List<User>> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, 
                                   List<User> users, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSON.toJSONString(users));  // Java→JSON字符串
    }

    @Override
    public List<User> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String json = rs.getString(columnName);
        return parseJson(json);
    }

    private List<User> parseJson(String json) {
        return json == null ? null : 
            JSON.parseObject(json, new TypeReference<List<User>>(){});
    }
    // 其他重写方法略...
}
④ 全局注册 TypeHandler
<!-- mybatis-config.xml -->
<typeHandlers>
    <typeHandler handler="com.example.ListUserTypeHandler" 
                javaType="java.util.List" jdbcType="VARCHAR"/>
</typeHandlers>
⑤ 实体类与 Mapper 映射
public class UserGroup {
    private Long id;
    @TableField(typeHandler = ListUserTypeHandler.class)
    private List<User> users;
    // getters/setters
}
<!-- UserGroupMapper.xml -->
<select id="selectUserGroup" resultType="UserGroup">
    SELECT * FROM user_group WHERE id = #{id}
</select>

四、测试与验证

UserGroup group = sqlSession.selectOne("selectUserGroup", 1L);
System.out.println(group.getUsers()); 
// 输出:[User{id=1, name='Alice', age=25}, User{id=2, name='Bob', age=30}]

五、总结与扩展

  1. 优势

    • 解耦业务与持久化逻辑:将类型转换代码集中管理,提升可维护性;
    • 支持复杂场景:通过自定义逻辑处理加密数据、多语言字段等特殊需求。
  2. 扩展方向

    • 泛型支持:抽象通用 JSON TypeHandler,通过 TypeReference 适配不同泛型类;
    • 性能优化:针对高频转换类型缓存解析结果,减少重复计算。

通过合理使用 TypeHandler,开发者可以显著提升 MyBatis 在处理复杂数据类型时的灵活性与代码整洁度,是高效 ORM 实践的重要工具。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring AI:让AI应用开发更简单

文章目录 引言什么是Spring AI&#xff1f;核心特性 Spring AI的核心组件ChatClient&#xff1a;聊天模型示例代码图示 ImageClient&#xff1a;图像生成示例代码图示 Prompt Templates&#xff1a;提示词模板示例代码 Spring AI的优势示例项目&#xff1a;智能机票助手代码实现…

【C】链式二叉树算法题1 -- 单值二叉树

leetcode链接https://leetcode.cn/problems/univalued-binary-tree/description/ 1 题目描述 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff1b;否则返回 false。 示例 1&#xff1…

什么是最终一致性,它对后端系统的意义是什么

最终一致性(Eventual Consistency)是分布式系统中的一种一致性模型。与传统的强一致性模型不同,最终一致性并不要求系统在任何时刻都保持一致,而是保证在足够的时间后,所有节点的数据最终会达到一致的状态。换句话说,系统允许短时间内出现数据的不一致性,但最终会通过某…

掌握大模型高效任务流搭建(一):构建LangChain任务流

前言&#xff1a; 在LangChain框架中&#xff0c;“链”占据着核心地位。它允许我们将众多任务模块串联起来&#xff0c;构建出富有弹性的任务流。借助这种链式结构&#xff0c;我们能够处理复杂的逻辑&#xff0c;并实现任务的自动化。在实际场景里&#xff0c;链式操作极大地…

目标检测——数据处理

1. Mosaic 数据增强 Mosaic 数据增强步骤: (1). 选择四个图像&#xff1a; 从数据集中随机选择四张图像。这四张图像是用来组合成一个新图像的基础。 (2) 确定拼接位置&#xff1a; 设计一个新的画布(输入size的2倍)&#xff0c;在指定范围内找出一个随机点&#xff08;如…

塑造网络安全的关键事件

注&#xff1a;本文为 “网络安全” 相关文章合辑。 机翻&#xff0c;未校。 Timeline of Cyber Security: Key Events that Shaped the Field 网络安全时间表&#xff1a;塑造该领域的关键事件 October 29, 2023 Cyberattacks are an everyday threat, always changing. T…

题解 | 牛客周赛82 Java ABCDEF

目录 题目地址 做题情况 A 题 B 题 C 题 D 题 E 题 F 题 牛客竞赛主页 题目地址 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 做题情况 A 题 判断字符串第一个字符和第三个字符是否相等 import java.io.*; import java.math.*; import java.u…

Redis 高可用性:如何让你的缓存一直在线,稳定运行?

&#x1f3af; 引言&#xff1a;Redis的高可用性为啥这么重要&#xff1f; 在现代高可用系统中&#xff0c;Redis 是一款不可或缺的分布式缓存与数据库系统。无论是提升访问速度&#xff0c;还是实现数据的高效持久化&#xff0c;Redis 都能轻松搞定。可是&#xff0c;当你把 …

uniapp-原生android插件开发摘要

uni-app在App侧的原生扩展插件&#xff0c;支持使用java、object-c等原生语言编写&#xff0c;从HBuilderX 3.6起&#xff0c;新增支持了使用uts来开发原生插件。 基础项目 UniPlugin-Hello-AS工程请在App离线SDK中查找 基础项目(App离线SDK)已经配置好了自定义插件所需要的…

【定昌Linux系统】部署了java程序,设置开启启动

将代码上传到相应的目录&#xff0c;并且配置了一个.sh的启动脚本文件 文件内容&#xff1a; #!/bin/bash# 指定JAR文件的路径&#xff08;如果JAR文件在当前目录&#xff0c;可以直接使用文件名&#xff09; JAR_FILE"/usr/local/java/xs_luruan_client/lib/xs_luruan_…

SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerApplicationContext构造方法

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args Sp…

Unity小功能实现:鼠标点击移动物体

1、功能描述 当玩家点击鼠标时&#xff0c;场景中的物体会移动到鼠标点击的位置。这个功能可以用于控制角色移动、放置物体等场景。 2、实现步骤 创建Unity项目&#xff1a;首先&#xff0c;打开Unity并创建一个新的3D项目。 添加3D物体&#xff1a;在场景中创建一个3D物体&am…

游戏引擎学习第127天

仓库:https://gitee.com/mrxiao_com/2d_game_3 为本周设定阶段 我们目前的渲染器已经实现了令人惊讶的优化&#xff0c;经过过去两周的优化工作后&#xff0c;渲染器在1920x1080分辨率下稳定地运行在60帧每秒。这个结果是意料之外的&#xff0c;因为我们没有预计会达到这样的…

Opencv 图像基本操作

1.1 数据读取-图像 opencv读取的格式是BGR而不是RGB import cv2 import matplotlib.pyplot as plt import numpy as np %matplotlib inline # 在Notebook的输出单元格内嵌入绘制的图形&#xff0c;而不在新窗口中显示img cv2.imread(cat.jpg) # cv2.IMREAD_COLOR&#xff1a…

【微知】ssh如何指定免密的2种简单方式?(vim ~/.ssh/authorized_keys、ssh-copy-id)

背景 ssh通过存储公钥到远端服务器&#xff0c;可以完成本端访问远端服务器的时候免密。免密原理是本端使用私钥&#xff0c;远端公钥&#xff0c;远端可以进行鉴权 方法1&#xff1a; vim ~/.ssh/authorized_keys 将本地电脑的pub的key直接copy到远端 ~/.ssh/authorized_ke…

Skywalking介绍,Skywalking 9.4 安装,SpringBoot集成Skywalking

一.Skywalking介绍 Apache SkyWalking是一个开源的分布式追踪与性能监视平台&#xff0c;特别适用于微服务架构、云原生环境以及基于容器&#xff08;如Docker、Kubernetes&#xff09;的应用部署。该项目由吴晟发起&#xff0c;并已加入Apache软件基金会的孵化器&#xff0c;…

卷积神经网络(cnn,He初始化+relu+softmax+交叉熵+卷积核,六)

He初始化relusoftmax交叉熵卷积核&#xff0c;才是cnn&#xff0c;我们推导的公式&#xff1a; **** &#xff08;p【k】-y【k】&#xff09;*drelu(yi[k])*w2[j, k]*drelu(hi[j])*x【i】 只能满足&#xff1a;He初始化relusoftmax交叉熵。 我们参考&#xff1a; cnn突破七…

【区块链 + 智慧政务】 伽罗华域:区块链数据溯源系统 | FISCO BCOS 应用案例

由北京伽罗华域科技有限公司打造的区块链数据溯源系统&#xff0c; 实现了数据从生产、管理到共享的全流程可追溯性和安全审计。系统支持数据的全生命周期管理&#xff0c; 包括数据采集、生产、共享等关键流程&#xff0c; 并通过智能合约自动执行数据的存证、共享与安全审计&…

矩阵基本概念

前言 本文隶属于专栏《机器学习数学通关指南》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见《机器学习数学通关指南》 正文 一句话理解矩阵 矩阵是数据排…

本地部署大语言模型-DeepSeek

DeepSeek 是国内顶尖 AI 团队「深度求索」开发的多模态大模型&#xff0c;具备数学推理、代码生成等深度能力&#xff0c;堪称"AI界的六边形战士"。 Hostease AMD 9950X/96G/3.84T NVMe/1G/5IP/RTX4090 GPU服务器提供多种计费模式。 DeepSeek-R1-32B配置 配置项 规…