【MyBatis-Plus 进阶学习笔记】

news2025/5/23 7:23:00

MyBatis-Plus 进阶学习笔记记录

    • 一、 MyBatis Plus 七大功能
    • 0. 数据准备
    • 1. 逻辑删除
    • 2. 自动填充
      • 2.1 优化1 自动填充 有的类没有更新和创建时间字段
      • 2.2 优化2 自己设置时间时填充自己设置的,不设置时自动填充
    • 3. 乐观锁插件 注:wrapper不能服用
    • 4. 性能分析插件
      • 4.1 PerformanceInterceptor 3.2.0版本被废除
      • 4.2 p6spy 使用
    • 5. 多租户SQL解析器
    • 6. 动态表名SQL解析器
    • 7. SQL注入器

一、 MyBatis Plus 七大功能

0. 数据准备

数据库表:
CREATE TABLE `user` (
  `id` bigint(20) NOT NULL COMMENT '主键 ',
  `name` varchar(30) DEFAULT NULL COMMENT '姓名',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  `manager_id` bigint(20) DEFAULT NULL COMMENT '直属上级id',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '修改时间',
  `version` int(11) DEFAULT '1' COMMENT '版本',
  `deleted` int(1) DEFAULT '0' COMMENT '逻辑删除标识(0未删除,1已删除)',
  PRIMARY KEY (`id`),
  KEY `manager_fk` (`manager_id`),
  CONSTRAINT `manager_fk` FOREIGN KEY (`manager_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
实体类:

@Data
@Accessors(chain = true)
@TableName("user")
public class User extends Model<User> implements Serializable {

    private static final long serialVersionUID = 1L;
    /**
     * 主键ID
     */
    @TableId(value = "id",type = IdType.AUTO)
    private Long id;

    /**
     * 姓名
     */
    @TableField("name")
    private String name;

    /**
     * 年龄
     */
    @TableField("age")
    private Integer age;

    /**
     * 邮箱
     */
    @TableField("email")
    private String email;

    @TableField("manager_id")
    private Long  manageId;

    /**
     * 出生时间
     */
    @TableField("create_time")
    private LocalDateTime createTime;
    @TableField("update_time")
    private LocalDateTime updateTime;

    /**
     * 是否置顶
     */
    @TableField("version")
    private Integer version;

    /**
     * 字段排除
     */
    @TableLogic
    @TableField("deleted")
    private Integer deleted;
}
xml配置:
server:
  port: 8088
spring:
  # 配置数据源信息
  datasource:
    # 配置连接数据库信息
    #本地地址:“127.0.0.1”
    #数据库名称:“db2”
    url: jdbc:mysql://127.0.0.1:3306/db2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
    #数据库账户
    username: root
    #数据库密码
    password: root
mybatis-plus:
  global-config:
    db-config:
    #逻辑删除字段
      logic-delete-field: deleted
      logic-delete-value: 1
      logic-not-delete-value: 0
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

1. 逻辑删除

逻辑删除语句:
 int i = userMapper.deleteById(2);
        System.out.println(i);
真实执行语句:
==>  Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0
==> Parameters: 2(Integer)
<==    Updates: 1
实际未删除,只修改删除字段的值
这时候如果执行查询语句,则只会展示逻辑删除为0的字段记录:
 List<User> list = userMapper.selectList(null);
        list.forEach(System.out::println);
虽然库中有三条记录但是有两条删除字段为1,则list中只展示一条
    @TableField(value = "deleted",select = false)
    private Integer deleted;
    select=false; 查询语句将不出现deleted字段

2. 自动填充

自动填充 创建和 更新时间
  @TableField(value = "create_time",fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @TableField(value = "update_time",fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        System.out.println("==============insertFill");
        setFieldValByName("createTime", LocalDateTime.now(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
        System.out.println("==============updateFill");
    }
}

2.1 优化1 自动填充 有的类没有更新和创建时间字段


@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        boolean hasSetter = metaObject.hasSetter("createTime");
        if (hasSetter){
            System.out.println("==============insertFill");
            setFieldValByName("createTime", LocalDateTime.now(),metaObject);
        }

    }

    @Override
    public void updateFill(MetaObject metaObject) {
        boolean hasSetter = metaObject.hasSetter("updateTime");
        if (hasSetter){
            setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
            System.out.println("==============updateFill");
        }

    }
}

2.2 优化2 自己设置时间时填充自己设置的,不设置时自动填充


@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        Object createTime = getFieldValByName("createTime", metaObject);
        if (ObjectUtils.isNull(createTime)){
            boolean hasSetter = metaObject.hasSetter("createTime");
            if (hasSetter){
                System.out.println("==============insertFill");
                setFieldValByName("createTime", LocalDateTime.now(),metaObject);
            }
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        Object updateTime = getFieldValByName("updateTime", metaObject);
        if (ObjectUtils.isNull(updateTime)){
            boolean hasSetter = metaObject.hasSetter("updateTime");
            if (hasSetter){
                setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
                System.out.println("==============updateFill");
            }
        }


    }
}

3. 乐观锁插件 注:wrapper不能服用

乐观锁和悲观锁是在并发编程中用来处理资源竞争和保证数据一致性的两种不同策略。它们各自适用于不同的使用场景:
乐观锁:
乐观锁的核心思想是假设并发访问的操作不会发生冲突,因此在读取资源时不会进行加锁,而是在更新资源时进行冲突检测。如果发现有其他线程已经对资源进行修改,则放弃当前操作或尝试重新执行。
使用场景:
并发写入操作较少的情况下,冲突发生的概率较低。
数据库表中的数据很少被修改,在持续时间较短的事务中进行读取操作。
适合处理乐观并发控制机制,如版本号或时间戳等。
悲观锁:
悲观锁的核心思想是假设并发访问的操作会发生冲突,因此在访问资源之前会进行加锁操作,确保在整个操作期间资源不被其他线程修改。
使用场景:
并发写入操作较多的情况下,冲突发生的概率较高。
数据库表中的数据经常被修改,在持续时间较长的事务中进行读取操作。
适合使用数据库的行级锁、表级锁或者分布式锁等来实现。
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //添加:分页插件
        //参数:new PaginationInnerInterceptor(DbType.MYSQL),是专门为mysql定制实现的内部的分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //添加:乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}
实体类字段:
    @TableField("version")
    @Version
    private Integer version;
    测试:
        int version=2;
        User user = new User();
        user.setId(1683667832465985538L);
        user.setEmail("lwx@qq.com");
        user.setName("lwx");
        user.setVersion(version);
        int update = userMapper.updateById(user);
        System.out.println(update);

4. 性能分析插件

4.1 PerformanceInterceptor 3.2.0版本被废除

 @Bean
    @Profile({"dev","test"}) // 指定环境
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor interceptor = new PerformanceInterceptor();
        // sql美化打印
        interceptor.setFormat(true);
        // 设置SQL超时时间
        interceptor.setMaxTime(500);
        //格式化语句
        performanceInterceptor.setFormat(true);
        return interceptor;
    }

4.2 p6spy 使用

<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>3.8.7</version>
</dependency>

#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
server:
  port: 8088
spring:
  # 配置数据源信息
  datasource:
    # 配置连接数据库信息
    #本地地址:“127.0.0.1”
    #数据库名称:“db2”
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://localhost:3306/db2?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    #数据库账户
    username: root
    #数据库密码
    password: root
mybatis-plus:
  global-config:
    db-config:
      #逻辑删除字段
      logic-delete-field: deleted
      logic-delete-value: 1
      logic-not-delete-value: 0
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

在这里插入图片描述

5. 多租户SQL解析器

6. 动态表名SQL解析器

7. SQL注入器

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

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

相关文章

SQL-每日一题【610.判断三角形】

题目 表: Triangle 写一个SQL查询&#xff0c;每三个线段报告它们是否可以形成一个三角形。 以 任意顺序 返回结果表。 查询结果格式如下所示。 示例 1: 解题思路 前置知识 CASE函数 CASE具有两种格式&#xff0c;简单CASE函数和CASE搜索函数。这两种方式&#xff0c;大部分…

SIGIR 2023 | 语音让对话推荐更easy,火山语音联合新加坡科学研究院发布业内首个语音对话推荐数据集

近年来&#xff0c;推荐系统在工业界取得了巨大成功&#xff0c;甚至成为互联网发展中不可或缺的增长引擎&#xff0c;基于此研究者们也在积极探索推荐系统的新形态&#xff0c;其中对话推荐系统&#xff08;Conversational Recommender System&#xff0c;简称CRS&#xff09;…

leetcode做题笔记37

编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&#xff09; 数独部分…

Flowable-UI

title: Flowable-UI date: 2023-7-23 12:19:20 tags: - Flowable Flowable-UI 安装 手把手教大家画了这样一个流程图&#xff0c;虽然说它不是特别好用&#xff0c;但是也不是不能用&#xff0c;也能用。好了&#xff0c;那么接下来的话&#xff0c;我们这个就先告一个段落&…

【OC总结 属性关键字】

文章目录 前言1. 属性关键字的分类2. 内存管理关键字2.1 weak2.2 assginweak和assgin的区别2.3 strong2.4 copy关键字copy关键字和strong的区别注意 2.5 多种copy模式&#xff1a;copy 和 mutableCopy 对 容器对象 进行操作2.6 问题总结 3. 线程安全的关键字 (nonatomic, atomi…

SpringBoot仅会SSM强撸项目--【JSB项目实战】

SpringBoot系列文章目录 SpringBoot知识范围-学习步骤【JSB系列之000】 文章目录 SpringBoot系列文章目录SpringBoot技术很多很多面对越来越紧的时间&#xff0c;越来越少的知识我要怎么办项目里可能要用到的技术前后端分离json其它的必要知识 环境及工具&#xff1a;上代码Co…

Java-IDEA好用的插件

Lombok&#xff0c;结合一些列注解&#xff0c;帮我们轻松解决重复编写实体类get、set、toString、build、构造方法等麻烦 Chinesepinyin-CodeComp&#xff0c;让界面汉化&#xff0c;使用起来更有亲和力 MyBatisX,点击小鸟图标&#xff0c;轻松再Mapper接口与xml文件之间实…

Spring Security OAuth2.0 - 学习笔记

一、OAuth基本概念 1、什么是OAuth2.0 OAuth2.0是一个开放标准&#xff0c;允许用户授权第三方应用程序访问他们存储在另外的服务提供者上的信息&#xff0c;而不需要将用户和密码提供给第三方应用或分享数据的所有内容。 2、四种认证方式 1&#xff09;授权码模式 2&#x…

云性能监控的应用是提升云服务质量的关键

随着云计算的普及和企业对云服务的广泛应用&#xff0c;保证云服务的质量和性能已成为企业的重要课题。在这一背景下&#xff0c;云性能监控应运而生&#xff0c;成为提升云服务质量的重要工具&#xff0c;也可以说云性能监控的应用是提升云服务质量的关键。 首先&#xff0c;云…

win10 hadoop报错 unable to load native-hadoop library

win10 安装hadoop执行hdfs -namenode format 和运行hadoop的start-all报错 unable to load native-hadoop library 验证&#xff1a; hadoop checknative -a 这个命令返回都是false是错的 返回下图是正确的 winutils: true D:\soft\hadoop-3.0.0\bin\winutils.exe Native li…

LLM-Blender:大语言模型也可以进行集成学习

最近在看arxiv的时候发现了一个有意思的框架&#xff1a;LLM-Blender&#xff0c;它可以使用Ensemble 的方法来对大语言模型进行集成。 官方介绍如下&#xff1a;LLM-Blender是一个集成框架&#xff0c;可以通过利用多个开源大型语言模型(llm)的不同优势来获得始终如一的卓越性…

pycharm 添加pyuic 插件

添加pyuic插件&#xff0c;就能将ui类型的文件转换称py格式的文件 进入主界面 打开文件->设置->外部工具 点击加号&#xff0c;添加扩展 图1 添加外部扩展 名字记作 pyuic&#xff0c;分组到External Tools 描述为ui to py ,地址选择为 python.exe 的目录地址 参数填写&a…

Python实现抽象工厂模式

抽象工厂模式是一种创建型设计模式&#xff0c;用于创建一系列相关或依赖对象的家族&#xff0c;而无需指定具体类。在Python中&#xff0c;可以通过类和接口的组合来实现抽象工厂模式。 下面是一个简单的Python实现抽象工厂模式的示例&#xff1a; # 抽象产品接口 class Abs…

客户案例 | 思腾合力服务器助力西安电子科技大学人工智能实验室建设

客户介绍 西安电子科技大学是以信息与电子学科为主&#xff0c;工、理、管、文多学科协调发展的全国重点大学&#xff0c;直属教育部&#xff0c;是国家“优势学科创新平台”项目和“211工程”项目重点建设高校之一、国家双创示范基地之一、首批35所示范性软件学院、首批9所示范…

微服务系列(1)-who i am?

微服务系列&#xff08;1&#xff09;-我是谁 应用架构的演化 简单来说系统架构可以分为以下几个阶段&#xff1a;复杂的臃肿的单体架构-SOA架构-微服务 单体架构及其所面临的问题 在互联网发展初期&#xff0c;用户数量少&#xff0c;流量小&#xff0c;硬件成本高。因此…

LangChain Agents深入剖析及源码解密上(一)

LangChain Agents深入剖析及源码解密上(一) LangChain Agents深入剖析及源码解密上 Agent工作原理详解 本节会结合AutoGPT的案例,讲解LangChain代理(Agent)为核心的内容。我们前面已经谈了代理本身的很多内容,也看了绝大部分的源代码,例如:ReAct的源代码,还有mrkl的源代…

HDFS基本操作命令

这里写目录标题 HDFS Shell CLI客户端说明常用命令hadoop fs -mkdir [-p] <path>hadoop fs -ls [-h] [-R] [<path>...]上传文件到指定目录下方法一:hadoop fs -put [-f] [-p] <localsrc>.....<dst>方法二&#xff1a;hadoop fs -moveFromLocal <loc…

金融机构如何管理UPS设备?这个方法超值!

UPS监控在金融行业中扮演着至关重要的角色&#xff0c;确保金融机构在电力故障或波动的情况下依然能够保持业务的稳定运行。 因此&#xff0c;UPS监控在金融行业中扮演着守护者的角色&#xff0c;确保金融机构能够在复杂的电力环境中持续稳健地运行。 客户案例 一家国际性的金…

数据库应用:Redis安装部署

目录 一、理论 1.缓存 2.关系型数据库与非关系型数据库 3.Redis 4.Redis安装部署 5.Redis命令工具 6.Redis数据库常用命令 7.Redis多数据库操作 二、实验 1.Redis安装部署 2.Redis命令工具 3.Redis数据库命令 4.Redis多数据库操作 三、问题 1.RESP连接CentOS 7 R…

KnowStreaming系列教程第二篇——项目整体架构分析

一、KS项目代码结构&#xff1a; ks项目代码结构如上&#xff1a; (1)km-console 是前端部分&#xff0c;基于React开发 (2)km-rest 是后端部分&#xff0c;主要是接受前端请求&#xff0c;对应controller相关代码所在模块 (3)km-biz:业务逻辑处理 (4)km-core:核心逻辑 (5…