【MyBatis-Plus 进阶学习笔记】

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注入器

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker续集+Docker Compose

目录 Containerd与docker的关系 runCrunC与Containerd的关联 OCI协议Dockerfile多阶段构建&#xff08;解决&#xff1a;如何让一个镜像变得更小 &#xff09;多阶段构建Images瘦身实践.dockerignore Docker Compose快速开始Quick StartCompose 命令常用命令命令说明 Compose 模…

吴师傅教你几招极速清理C盘,高能操作绝不让你失望!

电脑使用久了&#xff0c;C盘堆积的垃圾过多&#xff1b;每天上网会给电脑带来很多临时文件&#xff0c;这些垃圾文件不清理掉时间久了就会影响到电脑的运行速度&#xff1b;也会导致C盘变红&#xff0c;空间不足。那么&#xff0c;电脑C盘满了如何清理呢&#xff1f;教你几招极…

【MMdetection3d】Step1:环境搭建

Step1:环境搭建 1.创建并激活虚拟环境1.1 用官方Pytorch指令安装&#xff01;1.2 用官方mmcv指令安装&#xff01; 2 安装MMDetection3 克隆编译mmdetection3d4 环境测试5 测试demo 在Conda虚拟环境中搭建MMdetection3d环境 1.创建并激活虚拟环境 conda create -n mm3d python…

微信小程序:实现提示窗确定,取消执行不同操作(消息提示确认取消)showModal

效果 代码 wx.showModal({title: 提示,content: 是否确认退出,success: function (res) {if (res.confirm) {console.log(用户点击确定)} else if (res.cancel) {console.log(用户点击取消)}}})

一个开源的文件存储软件Filehub,不限速防和谐

FileHub介绍 一个基于Github开发的文件存储软件&#xff0c;美其名曰&#xff1a;FileHub&#xff0c;可存万物&#xff0c;而且绝不和谐任何文件。类似于百度云盘的功能&#xff0c;但是功能上肯定达不到百度云盘的效果&#xff0c;但是基本功能还是有的&#xff1a;例如登录注…

SpringBoot集成RocketMQ

SpringBoot整合RocketMQ使用非常简单&#xff0c;下面是一个简单的例子&#xff0c;作为备忘&#xff1a; 完整项目代码&#xff1a; https://github.com/dccmmtop/springBootRocketMQ 项目目录结构 依赖 <dependencies><dependency><groupId>org.apache.…

18.Netty源码之ByteBuf 详解

highlight: arduino-light ByteBuf 是 Netty 的数据容器&#xff0c;所有网络通信中字节流的传输都是通过 ByteBuf 完成的。 然而 JDK NIO 包中已经提供了类似的 ByteBuffer 类&#xff0c;为什么 Netty 还要去重复造轮子呢&#xff1f;本节课我会详细地讲解 ByteBuf。 JDK NIO…

VMware搭建Hadoop集群 for Windows(完整详细,实测可用)

目录 一、VMware 虚拟机安装 &#xff08;1&#xff09;虚拟机创建及配置 &#xff08;2&#xff09;创建工作文件夹 二、克隆虚拟机 三、配置虚拟机的网络 &#xff08;1&#xff09;虚拟网络配置 &#xff08;2&#xff09;配置虚拟机 主机名 &#xff08;3&#xf…

【LLM】大语言模型学习之LLAMA 2:Open Foundation and Fine-Tuned Chat Model

大语言模型学习之LLAMA 2:Open Foundation and Fine-Tuned Chat Model 快速了解预训练预训练模型评估微调有监督微调(SFT)人类反馈的强化学习(RLHF)RLHF结果局限性安全性预训练的安全性安全微调上手就干使用登记代码下载获取模型转换模型搭建Text-Generation-WebUI分发模型…

高效率,38V最大输入单电感同步升/降稳压器SYV939C

SYV939是一种高压同步降压-升压转换器。该器件工作在4V至28V的宽输入电压范围内&#xff0c;具有10max平均电感电流能力。四个集成的低RDS(ON)开关最大限度地减少了传导损耗。 SYV939c包括完整的保护功能&#xff0c;如输出过流/短路保护&#xff0c;过压保护和热停机&#xff…

了解Unity编辑器之组件篇Playables和Rendering(十)

Playables 一、Playable Director&#xff1a;是一种用于控制和管理剧情、动画和音频的工具。它作为一个中央控制器&#xff0c;可以管理播放动画剧情、视频剧情和音频剧情&#xff0c;以及它们之间的时间、顺序和交互。 Playable Director组件具有以下作用&#xff1a; 剧情控…

【MATLAB第61期】基于MATLAB的GMM高斯混合模型回归数据预测

【MATLAB第61期】基于MATLAB的GMM高斯混合模型回归数据预测 高斯混合模型GMM广泛应用于数据挖掘、模式识别、机器学习和统计分析。其中&#xff0c;它们的参数通常由最大似然和EM算法确定。关键思想是使用高斯混合模型对数据&#xff08;包括输入和输出&#xff09;的联合概率…

最新版Onenet云平台HTTP协议接入上传数据

2023年最新版Onenet更新后&#xff0c;原来的多协议接口已经找不到&#xff0c;由于需要用HTTP接入&#xff0c;就研究了一下新版Onenet云平台&#xff0c;搞清楚Onenet云平台的鉴权信息&#xff0c;就知道怎么上传数据了&#xff0c;包括后续上传实际数据&#xff0c;其实只需…

JVM简述

JDK&JRE&JVMJVM运行时内存结构图方法区堆区栈区程序计数器本地方法栈 JVM 的主要组成部分及其作用 JDK&JRE&JVM JVM就是java虚拟机&#xff0c;一台虚拟的机器&#xff0c;用来运行java代码 但并不是只有这台机器就可以的&#xff0c;java程序在运行时需要依赖…

【图论】kruskal算法

一.介绍 Kruskal&#xff08;克鲁斯卡尔&#xff09;算法是一种用于解决最小生成树问题的贪心算法。最小生成树是指在一个连通无向图中&#xff0c;选择一棵包含所有顶点且边权重之和最小的树。 下面是Kruskal算法的基本步骤&#xff1a; 将图中的所有边按照权重从小到大进行…

C# 快速写入日志 不卡线程 生产者 消费者模式

有这样一种场景需求&#xff0c;就是某个方法&#xff0c;对耗时要求很高&#xff0c;但是又要记录日志到数据库便于分析&#xff0c;由于访问数据库基本都要几十毫秒&#xff0c;可在方法里写入BlockingCollection&#xff0c;由另外的线程写入数据库。 可以看到&#xff0c;在…

2023河南萌新联赛第(三)场:郑州大学 A - 发工资咯

2023河南萌新联赛第&#xff08;三&#xff09;场&#xff1a;郑州大学 A - 发工资咯 时间限制&#xff1a;C/C 2秒&#xff0c;其他语言4秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld 题目描述 一个公司有n个人&#xff0c;每个月都…

TCP如何保证服务的可靠性

TCP如何保证服务的可靠性 确认应答超时重传流量控制滑动窗口机制概述发送窗口和接收窗口的工作原理几种滑动窗口协议1比特滑动窗口协议&#xff08;停等协议&#xff09;后退n协议选择重传协议 采用滑动窗口的问题&#xff08;死锁可能&#xff0c;糊涂窗口综合征&#xff09;死…

iostat工具使用

文章目录 iostat命令简介iostat命令参数 iostat输出信息CPU利用率输出信息磁盘利用率输出信息更详细的磁盘利用率输出信息 iostat命令使用示例iostat -kdx 1 iostat数据来源相关参考 iostat命令简介 iostat工具可用于CPU使用统计信息和设备的输入输出统计信息。iostat能支持显…

数据结构—数组和广义表

4.2数组 数组&#xff1a;按一定格式排列起来的&#xff0c;具有相同类型的数据元素的集合。 **一维数组&#xff1a;**若线性表中的数据元素为非结果的简单元素&#xff0c;则称为一维数组。 **一维数组的逻辑结构&#xff1a;**线性结构&#xff0c;定长的线性表。 **声明…