mybatisPlus3.5.2在NOT_NULL更新策略下自定义Mapper实现更新null值

news2024/11/17 8:35:29

版本

当前使用的mybatis plus版本如下
mybatis-plus-3.5.2.jar

默认更新配置

在这个更新策略下,调用mybatis基础的updateById等更新方法的时候会因为xml中的判断条件而更新不了null值,此时又不想修改全局的配置策略。

mybatis plus提供了
com.baomidou.mybatisplus.core.injector.AbstractMethod

com.baomidou.mybatisplus.core.injector.DefaultSqlInjector
让我们自定义mapper,在不影响全局更新策略的前提下,实现更新null值的需求。

其实本质就是在生成xml sql语句的时候把外面的if test判断给拿掉,这样在更新set时字段的值就能更新成和传入实体类相同的值。

后续只需要让我们的业务XXXBaseMapper继承我们自定义的mapper,然后调用我们制定的方法就行了。

mybatis-plus:
  global-config:
    db-config:
      insert-strategy: NOT_NULL
      update-strategy: NOT_NULL

代码demo

自定义mapper

package com.xxx.xxx;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;


public interface MyBaseMapper<T> extends BaseMapper<T> {
    
    //更新null值
    Integer myUpdateById(@Param(Constants.ENTITY) T entity);

}

定义生成的sql语句,去掉包裹的if条件

package com.xxx.xxx;

import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;

import java.util.*;

import static java.util.stream.Collectors.joining;

public class MyUpdateById extends AbstractMethod {


    public MyUpdateById(String methodName) {
        super(methodName);
    }

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        SqlMethod sqlMethod = SqlMethod.UPDATE_BY_ID;

        final String additional = optlockVersion(tableInfo) + tableInfo.getLogicDeleteSql(true, true);

        String sql = String.format(
                sqlMethod.getSql(),
                tableInfo.getTableName(),
                sqlSet(
                        tableInfo.isWithLogicDelete(),
                        false,
                        tableInfo,
                        false,
                        ENTITY,
                        ENTITY_DOT
                ),
                tableInfo.getKeyColumn(),
                ENTITY_DOT + tableInfo.getKeyProperty(),
                additional
        );

        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return addUpdateMappedStatement(mapperClass, modelClass, getMethod(sqlMethod), sqlSource);
    }


    protected String sqlSet(boolean logic, boolean ew, TableInfo table, boolean judgeAliasNull, final String alias,
                            final String prefix) {
        String sqlScript = this.getAllSqlSet(table, logic, prefix);
        if (judgeAliasNull) {
            sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", alias), true);
        }
        if (ew) {
            sqlScript += NEWLINE;
            sqlScript += convertIfEwParam(U_WRAPPER_SQL_SET, false);
        }
        sqlScript = SqlScriptUtils.convertSet(sqlScript);
        return sqlScript;
    }


    public String getAllSqlSet(TableInfo tableInfo, boolean ignoreLogicDelFiled, final String prefix) {
        final String newPrefix = prefix == null ? EMPTY : prefix;

        List<String> ignoreList = Arrays.asList("update_time", "create_time", "create_by", "update_by");

        return tableInfo.getFieldList().stream()
                .filter(i -> {
                    if (ignoreLogicDelFiled) {
                        return !(tableInfo.isWithLogicDelete() && i.isLogicDelete());
                    }
                    return true;
                }).map(i -> {
                    //ignoreList集合中的字段的更新策略还是按照配置来
                    //不在ignoreList集合中的字段则去掉xml的if条件
                    return i.getSqlSet(!ignoreList.contains(i.getColumn()), newPrefix);
                })
                .filter(Objects::nonNull)
                .collect(joining(NEWLINE));
    }


}

增加自定义的方法

package com.xxx.xxx;


import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class MySqlInjector extends DefaultSqlInjector {


    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
        //在原先的基础上加上自定义的方法
        methodList.add(new MyUpdateById("myUpdateById"));
        return methodList;
    }
}

然后我们自己的业务mapper继承MyBaseMapper,再调用myUpdateById既可以实现更新null值了。

查看方法生成的xml语句

原先生成xml是按照更新策略,更新的时候不能为null的。
在这里插入图片描述

我们自定义mapper中经过修改后生成的xml

在这里插入图片描述

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

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

相关文章

LeetCode091之解码方法(相关话题:动态规划)

题目描述 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; A -> "1" B -> "2" ... Z -> "26" 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可能有多种方法…

蓝奥声灯光联动在行业中的技术优势

随着科学技术的发展和人民生活水平的提高&#xff0c;人们对生活或工作的照明系统提出了新的要求&#xff0c;智能照明系统替代传统照明系统是家居智能化过程中必然要走的一步&#xff0c;传统的家居照明控制方式一般是通过电路中的开关来控制电路的导通与关断&#xff0c;开关…

【设计模式】我终于读懂了组合模式。。。

文章目录♈️学校院系展示需求♉️传统方案解决学校院系展示(类图)♐️传统方案解决学校院系展示存在的问题分析♊️组合模式基本介绍♋️组合模式原理类图♌️对原理结构图的说明-即(组合模式的角色及职责)♍️组合模式解决学校院系展示的 应用实例♎️接下来我们Debug下去看一…

【Python】搭建虚拟环境

目录 前言 虚拟环境简介 虚拟环境依赖模块的安装 1、安装好Python环境 2、安装第三方库&#xff08;虚拟环境库&#xff09; 3、 安装第三方模块virtualenvwrapper-win 为虚拟环境配置环境变量 1、配置环境变量 2、点击环境变量 3、在系统变量中&#xff0c;点击新建 …

TOOM网络舆情监控系统定制开发,舆情监控开源系统源码有哪些?

软件系统定制开发是指为满足客户特定业务需求而进行的软件系统开发工作。这通常涉及到对现有软件系统进行修改或开发新的软件系统来满足客户的特定要求。软件系统定制开发可以帮助客户解决其特定的业务问题&#xff0c;并为客户带来独特的竞争优势。TOOM网络舆情监控系统定制开…

安装龙蜥或CentOS 7时出现dracut- initqueue timeout解决方法

在安装龙蜥7.9操作系统时&#xff0c;出现dracut- initqueue timeout-starting…starting timeout scripts报错CentOS 7.9出现此问题也可以参考同样的方法如何制作启动盘和系统盘设置raid就不再赘述了&#xff0c;相关文档社区已经很多了&#xff0c;这里直接入正题一、问题描述…

自己搞个chatgpt机器人

chargpt确实越来越火了&#xff0c;目前来看很多文章都教大家如何去注册chatgpt&#xff0c;并且详细的科普了很多chatgpt种种神奇之处。我实际使用之后&#xff0c;确实也感觉非常奈斯。这里看到很多人用那个go环境的去对接个人微信&#xff0c;因此萌生了做个其他版本的想法。…

2022.12青少年软件编程(Python)等级考试试卷(一级)

2022.12青少年软件编程(Python)等级考试试卷(一级) 一、单选题(共25题,共50分) 1.关于Python语言的注释,以下选项中描述错误的是?( C ) A. Python语言有两种注释方式:单行注释和多行注释 B. Python语言的单行注释以#开头 C. Python多行注释使用###来做为标记 D. …

DPDK:UDP 协议栈的实现

文章目录1、DPDK 原理1.1、用户态驱动 IO1.2、内存池管理2、DPDK 启动设置3、DPDK&#xff1a;UDP 协议栈3.1、代码实现3.2、设置静态 arp4、DPDK&#xff1a;KNI4.1、代码实现4.2、程序测试文章参考<零声教育>的C/Clinux服务期高级架构系统教程学习&#xff1a; 服务器高…

缓存工作模型以及使用Redis为查询接口添加缓存

什么是缓存 缓存就是数据交换的缓冲区&#xff0c;是存储数据的临时地方&#xff0c;一般读写性能较高。在以前CPU需要将内存或磁盘中读到数据放寄存器才可以做运算&#xff0c;正是因此计算机运算的能力受到限制。为了解决&#xff0c;人们在CPU中设计了缓存&#xff0c;将一…

Word处理控件Aspose.Words功能演示:从 Java 中的 Word DOC 中提取图像

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c; Aspose API支持流行文件格式处…

Minecraft 1.19.2 Fabric模组开发 01.eclipse 开发包构建教程

1.19.2的离线开发包附文末 我们本次来进行Minecraft 1.19.2 Fabric模组开发教程的介绍&#xff0c;首先我们需要下载eclipse和openJDK eclipse下载 eclipse官网下载最新版 openJDK下载 下载最新版JDK 17.028 1.19.2 mdk下载 下载1.19.2MDK 注&#xff1a;1.19.2需要使…

OpenCV实战(6)——OpenCV策略设计模式

OpenCV实战&#xff08;6&#xff09;——OpenCV策略设计模式0. 前言1. 策略设计模式颜色识别1.1 颜色比较1.2 策略设计模式1.3 实现颜色比较1.4 ColorDetector 类1.4 计算两个颜色向量之间的距离2. 使用 OpenCV 函数3. 函子或函数对象4. OpenCV 算法的基类小结系列链接0. 前言…

一文带你攻克JDK新特性

1.Java8 新特性介绍 1.1 实验介绍 在国内&#xff0c;Java8 是当之无愧的普及率最高的 JDK 版本&#xff0c;从笔者工作开始&#xff0c; 就一直使用的是 JDK8 的版本&#xff0c;虽然现在 JDK19 即将面世&#xff0c;但是似乎依旧无法 动摇 JDK8 在国内的地位。这里面最主要…

leetcode-10:还原排列的最少操作步数

原题描述如下&#xff1a; 给你一个偶数 n​​​​​​ &#xff0c;已知存在一个长度为 n 的排列 perm &#xff0c;其中 perm[i] i​&#xff08;下标 从 0 开始 计数&#xff09;。 一步操作中&#xff0c;你将创建一个新数组 arr &#xff0c;对于每个 i &#xff1a; 如…

蓝桥杯-地宫取宝

算法分类&#xff1a; 动态规划 dp 问题描述 X 国王有一个地宫宝库&#xff0c;是 nm 个格子的矩阵&#xff0c;每个格子放一件宝贝&#xff0c;每个宝贝贴着价值标签。 地宫的入口在左上角&#xff0c;出口在右下角。 小明被带到地宫的入口&#xff0c;国王要求他只能向右…

使用DBeaver 连接时序数据库TDengine

介绍 TDengine 是一款高性能、分布式、支持 SQL 的时序数据库 (Database)。 DBeaver 是一款流行、开源的数据库管理工具以及 SQL 客户端&#xff0c;其功能强大&#xff0c;并且支持任何拥有 JDBC-Driver 的数据库&#xff08;这意味着几乎所有数据库都支持&#xff09;。 只…

Java面试常见问题-JVM篇

JVM面试问题汇总①什么是字节码&#xff0c;采用字节码的好处是什么⭐java类加载器有哪些⭐双亲委派模型⭐⭐GC是如何判断对象可以被回收总结了目前主流平台中常见的面试题&#xff0c;标⭐为重点&#xff01; 第一次更新节点&#xff1a;2023.1.8 什么是字节码&#xff0c;采用…

用nvidia-smi查看GPU的状态时,能耗pwr显示为ERR!

用nvidia-smi查看GPU的状态时&#xff0c;能耗pwr显示为ERR&#xff01; 解决方式&#xff1a; 以下代码查看具体的报错: dmesg -l err 如果有: NVRM:***说明硬件问题&#xff0c;需要更换 如果无错误&#xff0c;则参考如下&#xff1a; 1. 将你的工作站或者服务器报错的…

车载激光雷达赛道「新窗口」

车载激光雷达的降本逻辑&#xff0c;除了前装量产规模的加速&#xff0c;还有背后核心供应链的驱动。这也被视为激光雷达新周期的核心竞争力。 Lumotive是一家由微软创始人比尔盖茨投资的初创公司&#xff0c;为激光雷达公司提供基于波束转向技术的核心元器件&#xff0c;采用液…