MyBatis Plus:自定义typeHandler类型处理器

目录

引言:关于TypeHandler

PostGreSQL:JSON数据类型

PostGreSQL数据库驱动:PGobject类

TypeHandler类型处理器

自定义类型处理器

类型处理器实现:PGJsonTypeHandler

注册类型处理器


引言:关于TypeHandler

        MyBatis Plus提供了丰富的类型处理器TypeHandler,用于实现用于 JavaType 与 JdbcType 之间的转换,用于 PreparedStatement 设置参数值和从 ResultSet 或 CallableStatement 中取出一个值。

        但是,内置的类型处理器在某些特殊情况难以满足实际开发需求。以下,以PostGreSQL数据库中的JSON类型为例,叙述自定义类型处理器,实现java.util.Map与PostGreSQL中JSON类型之间的转换。

PostGreSQL:JSON数据类型

        使用SQL语句构建JSON类型字段值是十分简单的,

-- 简单标量/基本值
-- 基本值可以是数字、带引号的字符串、true、false或者null
SELECT '5'::json;-- 有零个或者更多元素的数组(元素不需要为同一类型)
SELECT '[1, 2, "foo", null]'::json;-- 包含键值对的对象
-- 注意对象键必须总是带引号的字符串
SELECT '{"bar": "baz", "balance": 7.77, "active": false}'::json;-- 数组和对象可以被任意嵌套
SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;

        问题在于:如何将java中的Map类型转换为PG数据库中的JSON字段值。

PostGreSQL数据库驱动:PGobject类

        在PostGreSQL数据库驱动依赖包的org.postgresql.util工具包下,挖出来了一个名称为:PGobject的类,

        该类(PGobject)的源码描述信息如下:

PGobject is a class used to describe unknown types An unknown type is any type that is unknown by JDBC Standards.

概略含义:PGobject是一个用于描述一种非JDBC标准的未知类型。

        可以看到,它内置了很多子类,用于描述PostGreSQL中的Line、Polygon、Money等数据类型。

         一通分析之后,发现PGobject类的type、value属性是比较重要的(毕竟只提供了这两个属性),

        查看源码之后,解读type和value字段的含义:

type:object对象的类型,

value:object对象的值。

        再拿来和PGpolygon子类做一下对比,会发现:type属性其实就是一个String字符串,用于描述PostGreSQL内置数据类型的名称;value则是具体的值。那么,我们也可以借助这个PGobject类来描述自己的类型。

TypeHandler类型处理器

        TypeHandler类型处理器是MyBatis/MyBatisPlus很重要的一部分内容,日常开发中,从数据表到JavaBean,从JavaBean到数据表,两者之间的转换全靠这些内置的TypeHandler来实现。

        查看TypeHandler的源码,内容如下,

/*** @author Clinton Begin*/
public interface TypeHandler<T> {void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;/*** Gets the result.** @param rs*          the rs* @param columnName*          Column name, when configuration <code>useColumnLabel</code> is <code>false</code>* @return the result* @throws SQLException*           the SQL exception*/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:是将JavaBean属性值转换为PostGreSQL支持的数据库字段值;

②3个getResult方法:熟悉原生JDBC编程的朋友应该都很眼熟,其实就是通过PreparedStatement执行完SQL之后,对ResultSet结果集进行按字段名columnName、按索引下标columnIndex,将PostGreSQL支持的数据库字段值,转换为JavaBean属性值的过程。

自定义类型处理器

        了解了上述内容之后,我们要自定义类型处理器,核心的工作就是:对TypeHandler接口提供的三个方式进行实现。

类型处理器实现:PGJsonTypeHandler

        以下给出一个Map集合类型到PostGreSQL-JSON数据类型之间的转换器实现类,相关部分可以直接查看代码注释,

/*** TypeHandler:类型处理器,用于 JavaType 与 JdbcType 之间的转换*  [1] 用于 PreparedStatement 设置参数值*  [2] 用于从 ResultSet CallableStatement 中取出一个值* PGJsonTypeHandler:处理Map集合类型与postgresql中JSON类型之间的转换*/@MappedTypes(value = {Object.class})
public class PGJsonTypeHandler<T> extends BaseTypeHandler<T> {//PGobject:PGobject is a class used to describe unknown types An unknown type is any type that is unknown by JDBC Standards.private static final PGobject pgObject = new PGobject();/*** 插入时设置参数类型* @param preparedStatement SQL预编译对象* @param i 需要赋值的索引位置(相当于在JDBC中对占位符的位置进行赋值)* @param parameter 索引位置i需要赋的值(原本要给这个位置赋的值,在setNonNullParameter方法中主要解决的问题就是将这个自定义类型变成数据库认识的类型)* @param jdbcType jdbc的类型* @throws SQLException*/@Overridepublic void setNonNullParameter(PreparedStatement preparedStatement, int i, T parameter, JdbcType jdbcType) throws SQLException {if (preparedStatement != null) {System.out.println("setNonNullParameter::"+parameter.toString());pgObject.setType("json");pgObject.setValue(JSON.toJSONString(parameter));preparedStatement.setObject(i, pgObject);}}/*** 转换为T类型实例* @param object 参数字符串({"name":"张三","age":18,"address":"北京市朝阳区"})或者null空值* @return T实例或者参数*/private T parseAsTInstance(Object object){//判空if(object == null){return null;}//处理字符串{"name":"张三","age":18,"address":"北京市朝阳区"}-转换为Map类型Map map = JSON.parseObject(object.toString(), Map.class);return (T)map;}/*** 获取时转换回的自定义类型* @param resultSet 结果集* @param s 列名称* @return Bean对象*/@Overridepublic T getNullableResult(ResultSet resultSet, String s) throws SQLException {Object object = resultSet.getObject(s);return parseAsTInstance(object);}/*** 获取时转换回的自定义类型* @param resultSet 结果集* @param i 列索引*/@Overridepublic T getNullableResult(ResultSet resultSet, int i) throws SQLException {Object object = resultSet.getObject(i);return parseAsTInstance(object);}/*** 获取时转换回的自定义类型* @param callableStatement 结果集* @param i 列索引*/@Overridepublic T getNullableResult(CallableStatement callableStatement, int i) throws SQLException {Object object = callableStatement.getObject(i);return parseAsTInstance(object);}
}

注册类型处理器

        要注册类型处理器,可以进行全局配置:typeHandlersPackage属性

        也可以在局部直接使用,例如:

package com.example.soil_backend.model.entity;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;import java.time.LocalDateTime;import com.baomidou.mybatisplus.annotation.TableId;import java.io.Serializable;
import java.util.Map;import com.example.soil_backend.model.TbBase;
import com.example.soil_backend.typehandler.PGJsonbTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;/*** 配置模板** @author XiMumu* @since 2024-02-18*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "tb_template", autoResultMap = true)
public class TbTemplate extends TbBase implements Serializable {private static final long serialVersionUID = -2288822970791637243L;/*** 主键ID*/@TableId(value = "id", type = IdType.AUTO)private Integer id;/*** 调查模板名称*/@TableField(value = "name")private String name;/*** 模板配置JSON*/@TableField(value = "config",typeHandler = PGJsonbTypeHandler.class)private Map config;/*** 是否删除:1-使用中;2-已删除*/@TableField(value = "del_flag")private Integer delFlag;}

      

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

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

相关文章

centos通过VNC连接

1.Centos上安装VNC服务端 yum list|grep vnc yum -y install tightvnc-server 2.windows电脑安装VNC客户端 下载并安装VNC-Viewer-7.9.0-Windows https://download.csdn.net/download/sj349781478/88856711 3.Centos启动VNC服务 #vncserver 4.通过客户端连接VNC服务端

kafka命令行操作

kafka命令行操作&#xff1a; 配置环境变量&#xff1a; export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk export JRE_HOME${JAVA_HOME}/jre export CLASSPATH.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH export JAVA_PATH${JAVA_HOME}/bin:${JRE_HOME}/bin export PATH…

AI顶流OpenAI又一重磅力作Sora,究竟是什么?一文弄懂Sora:简介|发展历程|主要功能|使用场景|替代软件|AI软件工具推荐!

要说最近一周的头条热搜&#xff0c;非Sora莫属&#xff01;Sora的诞生&#xff0c;再一次引发了人们对AI人工智能以及AIGC的关注。 对第一次听说Sora的人&#xff0c;可能会好奇&#xff0c;大家都在说的Sora是什么&#xff1f; Sora是什么软件&#xff1f; Sora&#xff0…

XML Map 端口进阶篇——常用关键字和格式化器详解

XML Map 端口是用于在不同XML之间建立关系映射的工具&#xff0c;允许通过拖拽操作实现源XML和目标 XML之间的数据字段映射&#xff0c;除此之外&#xff0c;XML Map 端口还提供了其它丰富多彩的功能&#xff0c;使用户能够更加灵活和高效的处理XML 数据映射任务&#xff0c;让…

解锁创意灵感,探索FlutterExampleApps项目的奥秘

解锁创意灵感&#xff0c;探索FlutterExampleApps项目的奥秘 项目简介 FlutterExampleApps项目是一个包含各种示例应用链接的仓库&#xff0c;旨在演示Flutter应用开发中的各种功能、特性和集成。 项目包含了以下几个部分&#xff0c;每个部分都涵盖了不同的内容和主题&…

使用 Next.js 连接 mysql 数据库

前言 本文主要为大家介绍&#xff0c;如何使用 Next 框架实现一个简单的后端接口&#xff0c;并且从数据库中请求数据返回给前端。 实现 创建api/getData文件夹 项目创建完成后在 app 文件下新建api文件夹&#xff0c;在 api 文件夹下新建 getData 文件夹&#xff0c;在 ge…

L1-047 装睡-java

输入格式&#xff1a; 输入在第一行给出一个正整数N&#xff08;≤10&#xff09;。随后N行&#xff0c;每行给出一个人的名字&#xff08;仅由英文字母组成的、长度不超过3个字符的串&#xff09;、其呼吸频率和脉搏&#xff08;均为不超过100的正整数&#xff09;。 输出格…

实现Slider 滑块组件标记动态变化

实现以上效果&#xff0c;下拉框、slider滑块、按钮都在同一行&#xff0c;设置flex布局后&#xff0c;发现silider滑块最右边的标记数字一直都如下竖着显示&#xff0c;后来通过给源组件的标记区.el-slider__marks-text增加一个宽度后解决该问题。 <template><div>…

如何使用IP代理解决亚马逊账号IP关联问题?

亚马逊账号IP关联问题是指当同一个IP地址下有多个亚马逊账号进行活动时&#xff0c;亚马逊会将它们关联在一起&#xff0c;从而可能导致账号被封禁或限制。 为了避免这种情况&#xff0c;许多人选择使用IP代理。 IP代理为什么可以解决亚马逊IP关联问题&#xff1f; IP代理是…

2.20 day2 QT

自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//窗口相关设置this->setWindowTitle("登入页面"); //设置 窗口 标题this->setWindowIcon(QIcon("D:…

算法项目(2)—— LSTM、RNN、GRU(SE注意力)、卡尔曼轨迹预测

本文包含什么? 项目运行的方式(包教会)项目代码LSTM、RNN、GRU(SE注意力)、卡尔曼四种算法进行轨迹预测.各种效果图运行有问题? csdn上后台随时售后.项目说明 本文实现了三种深度学习算法加传统算法卡尔曼滤波进行轨迹预测, 预测效果图 首先看下不同模型的指标: 模型RM…

佳能2580的下载手册

凡是和电子产品有关的产品其内部都开始不断地进行内卷&#xff0c;在不断地内卷背后&#xff0c;意味着科技更新和换代&#xff0c;自己也入手了一台佳能2580的打印机&#xff0c;一台相对比较老式的打印机&#xff0c;以此不断地自己想要进行打印的需要。 下载的基础步骤&…

调用接口时不时出现 Error: socket hang up

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 今天采用golang创建了一个http服务&#xff0c;准备对若干接口进行测试。 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 在测试第一个接口时&#xff0c;发现采用postman调用接口…

Jenkins 2.426.3新版设置中文

1. 插件页面显示无法联网 &#xff0c;点击Plugins一直提示连接超时&#xff0c;设置公司代理后 2. 稍等一会儿点击如下图&#xff0c;插件就出来了&#xff0c;然后输入Locale进行下载 3. 以下是我下载安装好的 4.打开设置&#xff0c;找到Locale选项&#xff0c;设置成zh_CN…

禁止电子邮箱地址登录WordPress后台的插件No Login by Email Address

WordPress 4.5及之后的版本增加了使用注册用户的电子邮件地址代替用户名登录的功能&#xff0c;但是大多数个人站长的管理员邮箱地址都是固定&#xff0c;而且到其他站点进行评论留言也是同一个邮箱地址&#xff0c;很容易给一些别有用心的可乘之机&#xff0c;所以禁止WordPre…

Java后端底座从无到有的搭建(随笔)

文章目录 开发模式的演变草创时期1.0时期&#xff08;基座时期&#xff09;1.1时期&#xff08;低代码时期&#xff09;2.0时期&#xff08;无代码时期&#xff09; 前言&#xff1a;本文是笔者在初创公司&#xff0c;一年多来Java后端服务底座搭建过程的总结&#xff0c;如有不…

Java 最全面试总结——4.Spring篇

1、什么是spring? Spring 是个 java 企业级应用的开源开发框架。 Spring 主要用来开发 Java 应用&#xff0c;但是有些扩展是针对 构建 J2EE 平台的 web 应用。 Spring 框架目标是简化 Java 企业级应用开发&#xff0c;并通过 POJO 为基础的编程 模型促进良好的编程习惯。…

Gradle统一管理依赖

背景 随着项目越来越大&#xff0c;module 越来越多&#xff0c;依赖的库也越来越多&#xff0c;依赖管理也越来越混乱。 我们一般会有以下需求&#xff1a; 1. 项目依赖统一管理&#xff0c;在单独文件中配置 2. 不同 Module 中的依赖版本号统一 管理 Gradle 依赖 说明&a…

【动态规划专栏】专题二:路径问题--------6.地下城游戏

本专栏内容为&#xff1a;算法学习专栏&#xff0c;分为优选算法专栏&#xff0c;贪心算法专栏&#xff0c;动态规划专栏以及递归&#xff0c;搜索与回溯算法专栏四部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn个人主页&#xff1a;小…

区块链游戏解说:什么是 Nine Chronicles

作者&#xff1a;lesleyfootprint.network 编译&#xff1a;cicifootprint.network 数据源&#xff1a; Nine Chronicles Dashboard 什么是 Nine Chronicles Nine Chronicles 是一款去中心化的在线角色扮演游戏&#xff0c;标志着在线游戏和区块链技术的发展。 Nine Chroni…