MybatisPlus字段类型处理器TypeHandler

news2024/12/12 21:36:24

个人博客:无奈何杨(wnhyang)

个人语雀:wnhyang

共享语雀:在线知识共享

Github:wnhyang - Overview


image

简介

官网:字段类型处理器

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

具体使用参考官网即可,不再过多copy了。官方示例工程:👉 mybatis-plus-sample-jsonb

coolGuard

这篇文章的来由还是要提到此项目:https://github.com/wnhyang/coolGuard/

最近在做规则版本控制过程中使用了到了“MybatisPlus字段类型处理器”,感觉挺好用的。

进度

1、【一般】完善入参和业务校验

入参校验主要使用validation注解实现,在controller层。业务校验在service层,主要用于处理NPE、唯一索引冲突等异常。

2、【重要】使用MybatisPlus字段类型处理器

替换掉原来手工处理Json字符串和Java实体类之间转换的步骤,简化了流程。

3、【重要】增加策略集和规则的版本控制

使用了和指标版本控制不同的做法,未来有可能以此替换掉之前的指标版本控制的方式。

4、【一般】增加一些接口:根据唯一索引的指标/策略集/策略/规则的查询、node相关的。

TODO

两个方向,1、消息模版,用于规则触发时,各种通道(短信、邮件、webhook)的消息模版;2、三方调用,项目中难免存在三方调用(IP、证件号、GPS、手机号解析,征信…),如何管理这些三方,如何抽象设计便于管理和编排?

顺便考虑前端项目的搭建,检查项目并修复问题。

使用

拿规则版本表举例,这里直接使用了Rule类作为版本表的行(实体类的属性),需要注意的是,在使用@TableField(value = "rule", typeHandler = JacksonTypeHandler.class)标注了类型处理器后,还需要在@TableName(value = "de_rule_version", autoResultMap = true)标识autoResultMap = truerule在表中对应的也是varchartext之类的字符串类型。

/**
 * 规则版本表
 *
 * @author wnhyang
 * @since 2024/08/29
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "de_rule_version", autoResultMap = true)
public class RuleVersion extends BasePO {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 规则编码
     */
    @TableField("code")
    private String code;

    /**
     * 条件
     */
    @TableField(value = "rule", typeHandler = JacksonTypeHandler.class)
    private Rule rule;

    /**
     * 策略集状态
     */
    @TableField("status")
    private Boolean status;

    /**
     * 版本号
     */
    @TableField("version")
    private Integer version;
}

MyBatis-Plus 内置了多种 JSON 类型处理器,包括 AbstractJsonTypeHandler 及其子类 Fastjson2TypeHandlerFastjsonTypeHandlerGsonTypeHandlerJacksonTypeHandler 等。这些处理器可以将 JSON 字符串与 Java 对象相互转换。

官方提供了多种类型转换器,这里是用的JacksonTypeHandler,其中有一个静态方法setObjectMapper给予用户自定义ObjectMapper的入口。如果你有使用一些Java8LocalDateTime等需要额外配置Jackson的,最好自己设置一下。

image

什么时候设置好呢?

其实官方也有示例:https://github.com/baomidou/mybatis-plus-samples/blob/master/mybatis-plus-sample-typehandler/src/main/java/com/baomidou/mybatisplus/samples/typehandler/config/MpJsonConfig.java

使用的是SpringBoot的扩展接口CommandLineRunner

关于SpringBoot的扩展点参考https://mp.weixin.qq.com/s/vc3GYcF4ldRYhUnfWovOtg

因为我有自己的Jackosn配置,所以直接注入即可。

/**
 * @author wnhyang
 * @date 2024/12/1
 **/
@Component
@RequiredArgsConstructor
public class AdminCommandLineRunner implements CommandLineRunner {

    private final ObjectMapper objectMapper;

    @Override
    public void run(String... args) throws Exception {
        JacksonTypeHandler.setObjectMapper(objectMapper);
    }
}

这样就可以愉快的完成Java对象到数据表的转换了!

应用

如果你有看过上篇文章指标版本控制,你会发现这样太方便了,主表和历史表设计会变得非常简单。

主表:idx1x2x3、等等,历史表:id、唯一索引(要暴露出来,方便操作)、主表、statusversion

无论主表如何设计,历史表通吃。

甚至不用考虑一个细节问题,还是那上篇文章举例,如下在灯泡处,也就是// 3、插入新纪录并加入chain的地方有一个指标转为指标历史的操作,这是存在问题的,因为id也被copy了,肯定会因为主键冲突导致插入历史表失败的情况。
在这里插入图片描述
如何解决呢?

要么copy后再次手动赋值null,这样插入时使用的就是自定义的主键生成策略生成的id

还有一种方式就是,对了忘了讲了我使用的MapStruct做的实体类的转换,所以像这个例子,可以标记一下忽略转换的字段,如下。

/**
 * 指标表版本表
 *
 * @author wnhyang
 * @since 2024/11/21
 */
@Mapper
public interface IndicatorVersionConvert {

    IndicatorVersionConvert INSTANCE = Mappers.getMapper(IndicatorVersionConvert.class);

    IndicatorVersionVO convert(IndicatorVersion po);

    PageResult<IndicatorVersionVO> convert(PageResult<IndicatorVersion> pageResult);

    @Mapping(target = "id", ignore = true)
    IndicatorVersion convert(Indicator indicator);
}

这样在编译后自然就不存在idcopy了。

image

小结

不得不说开发是越来越简单了,辅助工具越来越强大了,但不知道思考是不是会停滞不前呢?

难说!

写在最后

拙作艰辛,字句心血,望诸君垂青,多予支持,不胜感激。


个人博客:无奈何杨(wnhyang)

个人语雀:wnhyang

共享语雀:在线知识共享

Github:wnhyang - Overview

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c++编译版本问题#error C++17 or later compatible compiler is required to use xx

问题解决方向 网上多数给出的解决方法是找到setup.py&#xff0c;然后修改extra_compile_args参数中的cxx&#xff0c;由-stdc14改为-stdc17&#xff0c;但是这个方法在我这里没用。 所以我重新理解了下这个error&#xff0c;应该是说为了编译安装当前的库&#xff0c;需要的…

【AI大模型】大型语言模型LLM基础概览:技术原理、发展历程与未来展望

目录 &#x1f354; 大语言模型 (LLM) 背景 &#x1f354; 语言模型 (Language Model, LM) 2.1 基于规则和统计的语言模型&#xff08;N-gram&#xff09; 2.2 神经网络语言模型 2.3 基于Transformer的预训练语言模型 2.4 大语言模型 &#x1f354; 语言模型的评估指标 …

一文理解多模态大语言模型——下

作者&#xff1a;Sebastian Raschka 博士&#xff0c; 翻译&#xff1a;张晶&#xff0c;Linux Fundation APAC Open Source Evangelist 编者按&#xff1a;本文并不是逐字逐句翻译&#xff0c;而是以更有利于中文读者理解的目标&#xff0c;做了删减、重构和意译&#xff0c…

uC/OSII学习笔记(二)任务的堆栈检验

加入OSTaskCreateExt()创建拓展任务函数的使用。 加入OSTaskStkChk()堆栈检验函数的使用。 堆栈检验函数可检查任务堆栈的使用字节数量和空闲字节数量。 具体使用方法如下&#xff1a; 1.创建拓展任务OSTaskCreateExt()用于堆栈检验&#xff0c;堆栈检验必须用拓展任务OSTaskCr…

WPF+LibVLC开发播放器-进度条显示和拖动控制

进度条显示和拖动控制 视频教程界面上代码实现进度条显示进度进度条拖动视频进度 效果 视频教程 WPFLibVLC开发播放器-进度条控制 界面上 界面上线增加一个Slider控件&#xff0c;当做播放进度条 <SliderName"PlaySlider"Grid.Row"1"Width"800&qu…

【Rust WebAssembly 入门实操遇到的问题】

Rust WebAssembly 入门实操遇到的问题 什么是WebAssembly跟着教程走wasm-pack build error总结 什么是WebAssembly WebAssembly&#xff08;简称Wasm&#xff09;是一种基于堆栈的虚拟机的二进制指令 格式。Wasm 被设计为编程语言的可移植编译目标&#xff0c;支持在 Web 上部…

同为科技(TOWE)柔性定制化PDU插座

随着科技的进步&#xff0c;越来越多的精密电子设备&#xff0c;成为工作生活密不可分的工具。 电子电气设备的用电环境也变得更为复杂&#xff0c;所以安全稳定的供电是电子电气设备的生命线。 插座插排作为电子电气设备最后十米范围内供配电最终核心部分&#xff0c;便捷、安…

AI RPA 影刀基础教程:开启自动化之旅

RPA 是什么 RPA 就是机器人流程自动化&#xff0c;就是将重复的工作交给机器人来执行。只要是标准化的、重复的、有逻辑行的操作&#xff0c;都可以用 RPA 提效 准备 安装并注册影刀 影刀RPA - 影刀官网 安装 Chrome 浏览器 下载链接&#xff1a;Google Chrome 网络浏览器 …

HTTP 长连接(HTTP Persistent Connection)简介

HTTP长连接怎么看&#xff1f; HTTP 长连接&#xff08;HTTP Persistent Connection&#xff09;简介 HTTP 长连接&#xff08;Persistent Connection&#xff09;是 HTTP/1.1 的一个重要特性&#xff0c;它允许在一个 TCP 连接上发送多个 HTTP 请求和响应&#xff0c;而无需为…

VS与SQL Sever(C语言操作数据库)

作者这里使用的是程序是&#xff1a; Visual Studio SQL Sever (1 对VS的操作 1.首先我们打开Visual Studio Installer&#xff0c;并以管理员身份运行 2.点击修改 3.先选择数据存储和处理&#xff0c;再在右方添加处理工具&#…

基于“开源 2+1 链动 O2O 商城小程序”的门店拉新策略与流程设计

摘要&#xff1a;在数字化商业浪潮席卷之下&#xff0c;实体门店面临着激烈的市场竞争&#xff0c;如何高效拉新成为关乎门店生存与发展的关键问题。本文聚焦于“开源 21 链动 O2O 商城小程序”&#xff0c;深入探讨结合多种手段的门店拉新策略及详细流程设计。通过剖析到店扫码…

微服务即时通讯系统(5)用户管理子服务,网关子服务

用户管理子服务&#xff08;user文件&#xff09; 用户管理子服务也是这个项目中的一个业务最多的子服务&#xff0c;接口多&#xff0c;但是主要涉及的数据表只有user表&#xff0c;Redis的键值对和ES的一个搜索引擎&#xff0c;主要功能是对用户的个人信息进行修改管理&#…

ceph的存储池管理

1 查看存储池信息 查看存储池的名称 [rootceph141ceph]# ceph osd pool ls .mgr查看存储池机器编号 [rootceph141ceph]# ceph osd pool ls 1 .mgr查看存储池的详细信息 [rootceph141ceph]# ceph osd pool ls detail pool 1 .mgr replicated size 3 min_size 2 crush_rule 0 ob…

Spring和SpringBoot的关系和区别?

大家好&#xff0c;我是锋哥。今天分享关于【Spring和SpringBoot的关系和区别&#xff1f;】面试题。希望对大家有帮助&#xff1b; Spring和SpringBoot的关系和区别&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring和Spring Boot是两种相关但有所…

21个Python脚本自动执行日常任务(1)

引言 作为编程领域摸爬滚打超过十年的老手&#xff0c;我深刻体会到&#xff0c;自动化那些重复性工作能大大节省我们的时间和精力。 Python以其简洁的语法和功能强大的库支持&#xff0c;成为了编写自动化脚本的首选语言。无论你是专业的程序员&#xff0c;还是希望简化日常工…

蘑菇书(EasyRL)学习笔记(3)

q1、学习与规划 学习&#xff08;learning&#xff09;和规划&#xff08;planning&#xff09;是序列决策的两个基本问题。如下图所示&#xff0c;在强化学习中&#xff0c;环境初始时是未知的&#xff0c;智能体不知道环境如何工作&#xff0c;它通过不断地与环境交互&#x…

46 基于单片机的烧水壶系统设计

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STC89C52RC单片机&#xff0c;采用四个按键&#xff0c;通过DS18B20检测温度&#xff0c;开机显示实时温度 第一个按键为切换功能按键&#xff0c;按下后&#xff0c;可以设置烧水温度的大小&…

谈论 PHP与XSS

本文将讨论一些脚本攻击问题&#xff0c;以及如何解决XSS脚本攻击问题 美好的周末就用来学点知识吧&#xff01;&#xff01;&#xff01; ———————————————————————————————————— 文章目录 XSS跨站脚本攻击XSS是什么XSS类型&#xff1a;反…

用micropython 操作stm32f4单片机的定时器实现蜂鸣器驱动

import pyb import time # 初始化引脚和定时器通道作为PWM输出 # 注意&#xff1a;这里我们假设您使用的是支持PWM的引脚和定时器 # 在不同的MicroPython板上&#xff0c;支持的引脚和定时器可能不同 # 请查阅您的板的文档以确认正确的引脚和定时器 buzzer_pin pyb.Pin(PD15,…

Ubuntu20.04双系统安装详解(内容详细,一文通关!)

Ubuntu20.04作为现今ubuntu非常稳定的一个版本&#xff0c;是大家入门ubnutu的非常奈斯的版本选择。接下来介绍一下在windows上配置ubuntu双系统的方式&#xff0c;该篇博文主要参考b站用户“机器人工匠阿杰”的双系统安装教学视频&#xff0c;传送门如下&#xff1a; &#x…