【第24章】MyBatis-Plus之SQL注入器

news2024/9/21 14:39:44

文章目录

  • 前言
  • 一、概述
    • 1. 使用场景
    • 2. 功能
  • 二、注入器配置
  • 三、自定义全局方法攻略
    • 1. 定义SQL
    • 2. 注册自定义方法
    • 3.定义BaseMapper
    • 4.配置SqlInjector
  • 四、注意事项
  • 五、更多示例
  • 六、实战
    • 1. 定义SQL
    • 2. 注册自定义方法
    • 3.定义BaseMapper
    • 4.配置SqlInjector
    • 5. 测试类
    • 6. 结果
  • 总结


前言

MyBatis-Plus 提供了灵活的机制来注入自定义的 SQL 方法,这通过 sqlInjector 全局配置实现。通过实现 ISqlInjector 接口或继承 AbstractSqlInjector 抽象类,你可以注入自定义的通用方法到 MyBatis 容器中。


一、概述

SQL注入器允许开发者扩展和定制SQL语句的生成,以适应特定的业务逻辑和查询需求。以下是SQL注入器的一些示例使用场景和它能实现的功能:

1. 使用场景

  • 自定义查询方法:当标准的CRUD操作无法满足复杂的查询需求时,可以通过SQL注入器添加自定义的查询方法。

  • 复杂数据处理:在需要进行复杂的数据处理,如多表联结、子查询、聚合函数等时,SQL注入器可以帮助生成相应的SQL语句。

  • 性能优化:通过自定义SQL语句,可以针对特定的查询场景进行性能优化。

  • 数据权限控制:在需要根据用户权限动态生成SQL语句时,SQL注入器可以用来实现数据权限的控制。

  • 遗留系统迁移:在将遗留系统迁移到MyBatis-Plus时,可能需要保留原有的SQL语句结构,SQL注入器可以帮助实现这一过渡。

2. 功能

  • 注入自定义SQL方法:通过实现ISqlInjector接口,可以注入自定义的SQL方法到MyBatis容器中,这些方法可以是任何复杂的SQL查询。

  • 扩展BaseMapper:可以在继承BaseMapper的基础上,通过SQL注入器添加额外的查询方法,这些方法将自动被MyBatis-Plus识别和使用。

  • 灵活的SQL生成:SQL注入器提供了灵活的SQL生成机制,可以根据业务需求生成各种SQL语句,包括但不限于SELECT、INSERT、UPDATE、DELETE等。

  • 集成第三方数据库功能:如果需要使用数据库的特定功能,如存储过程、触发器等,SQL注入器可以帮助生成调用这些功能的SQL语句。

  • 动态SQL支持:在某些场景下,SQL语句需要根据运行时的条件动态生成,SQL注入器可以支持这种动态SQL的生成。

通过SQL注入器,MyBatis-Plus提供了一个强大的扩展点,使得开发者能够根据项目的具体需求,灵活地定制和优化SQL语句,从而提高应用的性能和适应性。

二、注入器配置

MyBatis-Plus中,sqlInjector 配置是一个全局配置项,用于指定一个实现了 ISqlInjector 接口的类,该类负责将自定义的SQL方法注入到MyBatisMapper接口中。

ISqlInjector.java
public interface ISqlInjector {

    /**
     * 检查SQL是否已经注入(已经注入过不再注入)
     *
     * @param builderAssistant mapper 构建助手
     * @param mapperClass      mapper 接口的 class 对象
     */
    void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass);
}

默认的注入器实现是 DefaultSqlInjector,你可以参考它来创建自己的注入器。

以下是如何配置 sqlInjector 的示例。

根据提供的参考信息,我们可以看到如何在MyBatis-Plus中实现自定义的全局方法,包括逻辑删除、自动填充以及自定义的insertinsertBatch方法。下面是一个更详细的步骤说明和示例代码:

三、自定义全局方法攻略

1. 定义SQL

首先,你需要定义自定义方法的SQL语句。这通常在继承了AbstractMethod的类中完成,例如MysqlInsertAllBatch

public class MysqlInsertAllBatch extends AbstractMethod {
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        // 定义SQL语句
        String sql = "INSERT INTO " + tableInfo.getTableName() + "(" + StringUtils.join(tableInfo.getFieldList(), ",") + ") VALUES " +
                      "(#{list[0].id}, #{list[0].name}, #{list[0].age}), " +
                      "(#{list[1].id}, #{list[1].name}, #{list[1].age})";
        // 第三个参数必须和baseMapper的自定义方法名一致
        return this.addInsertMappedStatement(mapperClass, modelClass, "mysqlInsertAllBatch", sqlSource, new NoKeyGenerator(), null, null);
    }
}

2. 注册自定义方法

接下来,你需要创建一个类来继承DefaultSqlInjector,并重写getMethodList方法来注册你的自定义方法。

public class MyLogicSqlInjector extends DefaultSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        methodList.add(new DeleteAll());
        methodList.add(new MyInsertAll());
        methodList.add(new MysqlInsertAllBatch());
        return methodList;
    }
}

3.定义BaseMapper

然后,你需要在你的BaseMapper接口中定义自定义的方法。

public interface MyBaseMapper<T> extends BaseMapper<T> {

    Integer deleteAll();

    int myInsertAll(T entity);

    int mysqlInsertAllBatch(@Param("list") List<T> batchList);
}

4.配置SqlInjector

最后,你需要在配置文件中指定你的自定义SQL注入器。
application.yml 中配置

mybatis-plus:
  global-config:
    sql-injector: com.example.MyLogicSqlInjector

application.properties 中配置

mybatis-plus.global-config.sql-injector=com.example.MyLogicSqlInjector

四、注意事项

  • 在定义自定义方法时,确保方法名与注入的SQL语句中的ID一致。
  • 在使用自定义的批量插入和自动填充功能时,确保在Mapper方法的参数上使用@Param注解,并且命名符合MyBatis-Plus的默认支持(list, collection, array)。
  • 自定义的SQL语句应该根据你的业务需求来编写,确保它能够正确地执行你想要的操作。
  • 通过以上步骤,你就可以在MyBatis-Plus中成功地实现自定义的全局方法了。记得在实际使用中,根据你的业务需求调整SQL语句和方法的实现。

五、更多示例

参考 自定义 BaseMapper 示例,你可以找到如何创建自定义的 SQL 注入器和如何在项目中使用它们的详细步骤。

通过这种方式,MyBatis-Plus 允许你扩展其功能,以满足特定的业务需求,同时保持代码的整洁和可维护性。

六、实战

大家注意,官方文档应该是好久没更新了,操作上略有区别,整体流程一致

1. 定义SQL

package org.example.springboot3.mybatisplus.util;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;

/**
 * Create by zjg on 2024/7/6
 */
public class MysqlInsertAllBatch extends AbstractMethod {

    protected MysqlInsertAllBatch(String methodName) {
        super(methodName);
    }

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        // 定义SQL语句
        String sql = "INSERT INTO " + tableInfo.getTableName() + "(id,name,age) VALUES " +
                "(#{list[0].id}, #{list[0].name}, #{list[0].age}), " +
                "(#{list[1].id}, #{list[1].name}, #{list[1].age})";
        //第三个参数必须和baseMapper的自定义方法名一致
        return this.addInsertMappedStatement(mapperClass, modelClass, "mysqlInsertAllBatch", this.createSqlSource(this.configuration,sql,modelClass), new NoKeyGenerator(), null, null);
    }
}

2. 注册自定义方法

接下来,你需要创建一个类来继承DefaultSqlInjector,并重写getMethodList方法来注册你的自定义方法。

package org.example.springboot3.mybatisplus.util;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.session.Configuration;
import java.util.List;

/**
 * Create by zjg on 2024/7/6
 */
public class MysqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Configuration configuration, Class<?> mapperClass, TableInfo tableInfo) {
        List<AbstractMethod> methodList = super.getMethodList(configuration,mapperClass,tableInfo);
        methodList.add(new MysqlInsertAllBatch("mysqlInsertAllBatch"));
        return methodList;
    }
}

3.定义BaseMapper

package org.example.springboot3.mybatisplus.mappers;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.example.springboot3.mybatisplus.model.User;
import java.util.List;

/**
 * Create by zjg on 2024/5/19
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {
    int mysqlInsertAllBatch(@Param("list") List<User> batchList);
}

4.配置SqlInjector

在这里插入图片描述
这里我们来声明个bean对象

package org.example.springboot3.mybatisplus.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.example.springboot3.mybatisplus.util.MysqlInjector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Create by zjg on 2024/5/29
 */
@Configuration
public class MybatisPlusConfig {
    @Bean
    public ISqlInjector iSqlInjector(){
        return new MysqlInjector();
    }
}

5. 测试类

@RequestMapping("sql-inject")
public void sqlInject(){
    User user1 = new User(2002, "小红", 18);
    User user2 = new User(2003, "小黄", 18);
    List<User> list=new ArrayList<>();
    list.add(user1);
    list.add(user2);
    int i = userService.getBaseMapper().mysqlInsertAllBatch(list);
    System.out.println(i);
}

6. 结果

在这里插入图片描述

这里自动填充没有生效,有需要的话可以在定义SQL的地方添加上。


总结

回到顶部

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

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

相关文章

如何使用IDEA快速清理无效代码(荣耀典藏版)

大家好&#xff0c;我是月夜枫。 今天分享一下IDEA中很有实用价值的Analyze&#xff0c;那么Analyze是用来做什么的呢&#xff1f; 主要用来清理没有引用的代码&#xff0c;包括方法、实体类以及没有使用的Mapper和Service等。 为了是项目更加整洁&#xff0c;可以使用Idea中…

(十六)视图变换 正交投影 透视投影

视图变换 代码实验 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostream> #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h"//GLM #include <glm/glm.hpp> #include <glm/gtc/m…

SECS/GEM快速完成半导体设备通讯

金南瓜帮助国内大量从事半导体前道设备开发研制、生产的设备厂商&#xff0c;通过快速提供稳定可靠的SECS/GEM、GEM300产品&#xff0c;为客户在激光退火、湿法设备&#xff08;清洗、镀膜等&#xff09;、离子注入、MOCVD、PVD等客户专注于核心工艺提升&#xff0c;提升企业的…

【Python进阶】继承进阶和私有权限

目录 一、继承进阶 1、方法重写 2、调用父类方法 3、多层继承 二、私有权限 1、私有属性 2、私有方法 面向对象基础&#xff1a;小白也能看懂的Python基础教程&#xff08;8&#xff09;-CSDN博客 一、继承进阶 1、方法重写 当父类的同名方法达不到子类的要求&#x…

AR增强现实汽车装配仿真培训系统开发降低投入费用

随着互联网的无处不在&#xff0c;AR增强现实技术正逐步融入我们生活的每一个角落。深圳华锐视点作为一家引领行业潮流的AR内容开发的技术型公司&#xff0c;正以其卓越的技术实力和专业的服务团队&#xff0c;推动着国内AR技术向更加成熟和多元化的方向迈进。 深圳华锐视点提供…

2024年文化研究与数字媒体国际会议 (CRDM 2024)

2024年文化研究与数字媒体国际会议 (CRDM 2024) 2024 International Conference on Cultural Research and Digital Media 【重要信息】 大会地点&#xff1a;珠海 大会官网&#xff1a;http://www.iccrdm.com 投稿邮箱&#xff1a;iccrdmsub-conf.com 【注意&#xff1a;稿将…

深入探索联邦学习框架 Flower

联邦学习框架 本文主要期望介绍一个设计良好的联邦学习框架 Flower&#xff0c;在开始介绍 Flower 框架的细节前&#xff0c;先了解下联邦学习框架的基础知识。 作为一个联邦学习框架&#xff0c;必然会包含对横向联邦学习的支持。横向联邦是指拥有类似数据的多方可以在不泄露…

【算法】代码随想录之数组(更新中)

文章目录 前言 一、二分查找法&#xff08;LeetCode--704&#xff09; 二、移除元素&#xff08;LeetCode--27&#xff09; 前言 跟随代码随想录&#xff0c;学习数组相关的算法题目&#xff0c;记录学习过程中的tips。 一、二分查找法&#xff08;LeetCode--704&#xff0…

【环境准备】 Vue环境搭建

文章目录 前言vue-cli 安装创建项目3.0、以下3.0 、以上 前言 书接上回《NodeJs(压缩包版本)安装与配置》&#xff0c;安装完了NodeJs&#xff0c;接下来就要配置vue的环境了。 vue-cli 安装 安装vue-cli输入如下命令 #&#xff08;安装的是最新版&#xff09; npm install …

Nacos 国际化

项目需要&#xff0c;后端异常信息需要进行国际化处理。所以想有没有方便易用的可选项。 1、国际化配置调整&#xff0c;不需要重启系统 2、可支持添加不同或自定义语言包&#xff08;就是配置的资源文件&#xff09; 参考&#xff1a; Nacos实现SpringBoot国际化的增强_spr…

嵌入式代码升级——IAP

目录 IAP的特点 实现 IAP 功能 STM32 正常的程序运行流程 STM32 加入IAP后的运行流程 程序执行流程 BootLoader程序 APP1程序 APP2程序 验证操作步骤 IAP&#xff08;In-Application Programming&#xff09;指的是在应用程序运行时对其自身的Flash存储器进行编程的操作…

修复 Ubuntu 24.04 Dock 丢失应用程序图标

找出应用程序窗口的类名 首先&#xff0c;您需要启动应用程序窗口。然后&#xff0c;按 Alt F2 启动“运行 Command”对话框。当对话框打开时&#xff0c;输入 lg 并按 Enter 键。 在该窗口中&#xff0c;单击Windows按钮&#xff0c;然后找出目标应用程序窗口的类名称。 在/…

激光干涉仪可以完成哪些测量:全面应用解析

在高端制造领域&#xff0c;精度是衡量产品质量的关键指标之一。激光干涉仪作为一项高精度测量技术&#xff0c;其应用广泛&#xff0c;对于提升产品制造精度具有重要意义。 线性测量&#xff1a;精确定位的基础 激光干涉仪采用迈克尔逊干涉原理&#xff0c;实现线性测量。该…

怎么转播别人的直播

转播别人的直播&#xff0c;特别是实现无缝的实时转播&#xff0c;可以通过一些平台的功能来实现&#xff0c;比如快手和抖音。下面是一个基本的步骤说明&#xff0c;但请注意&#xff0c;具体操作可能会因平台更新或政策变化而有所不同&#xff1a; 找到想要转播的直播间&…

Vue打包文件dist放在SpringBoot项目下运行(正确实现全过程)

项目开发中&#xff0c;一般我们都会使用SpringBootVue进行前后端开发。 在部署时&#xff0c;会后端启动一个服务&#xff0c;再启动一个nginx&#xff0c;nginx中配置前端打包文件dist进行项目访问。 实际上&#xff0c;我们也可以把打包好的dist目录放在SpringBoot项目下进…

初识STM32:寄存器编程 × 库函数编程 × 开发环境

STM32的编程模型 假如使用C语言的方式写了一段程序&#xff0c;这段程序首先会被烧录到芯片当中&#xff08;Flash存储器中&#xff09;&#xff0c;Flash存储器中的程序会逐条的进入CPU里面去执行。 CPU相当于人的一个大脑&#xff0c;虽然能执行运算和执行指令&#xff0c;…

C++视觉开发 五.答题卡识别

目录 一.单道题目的识别 1.基本流程及原理 2.实现程序 二.整张答题卡原理 1.图像预处理 Canny 边缘检测 2.答题卡处理 cv::warpPerspective cv::getPerspectiveTransform 3.筛选出所有选项 cv::boundingRect 4.将选项按题目分组 三.完整实现程序 1.实现代码 2.结…

支付宝沙箱对接(GO语言)

支付宝沙箱对接 1.1 官网1.2 秘钥生成&#xff08;系统默认&#xff09;1.3 秘钥生成&#xff08;软件生成&#xff09;1.4 golan 安装 SDK1.5 GoLand 代码1.6 前端代码 1.1 官网 沙箱官网: https://open.alipay.com/develop/sandbox/app 秘钥用具下载&#xff1a; https://ope…

MSPM0G3507——超声波模块移植代码

超声波没有做单独的代码文件 直接自己创建.c.h文件&#xff0c;将这些复制粘贴即可&#xff0c;然后进行SYSCFG配置按照这些配置即可&#xff0c;有啥问题直接评论区提出&#xff0c;如果看不懂的话评论区说一下&#xff0c;再出讲解 超声波.c文件 #include "ti_msp_dl…

线程并发库复习

1.进行和线程 什么是进程&#xff1a;进程是内存分配的基本单位&#xff0c;它是程序执行时的一个实例&#xff0c;会被放到进程就绪队列&#xff0c;等进程调度器选择它&#xff0c;给它时间片&#xff0c;它才会运行。在java中启动进程&#xff0c;main&#xff0c;test&…