【MyBatis-Plus 进阶学习笔记】

news/2024/11/29 20:49:44/

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: deletedlogic-delete-value: 1logic-not-delete-value: 0configuration: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 {@Overridepublic void insertFill(MetaObject metaObject) {System.out.println("==============insertFill");setFieldValByName("createTime", LocalDateTime.now(),metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {setFieldValByName("updateTime", LocalDateTime.now(),metaObject);System.out.println("==============updateFill");}
}

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


@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {boolean hasSetter = metaObject.hasSetter("createTime");if (hasSetter){System.out.println("==============insertFill");setFieldValByName("createTime", LocalDateTime.now(),metaObject);}}@Overridepublic 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 {@Overridepublic 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);}}}@Overridepublic 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 {@Beanpublic 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")@Versionprivate 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.P6SpyDriverurl: 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: deletedlogic-delete-value: 1logic-not-delete-value: 0configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

在这里插入图片描述

5. 多租户SQL解析器

6. 动态表名SQL解析器

7. SQL注入器


http://www.ppmy.cn/news/979105.html

相关文章

Redis DeskTop Manager 使用教程

简单粗暴的介绍一下&#xff0c;以及在工作中如何去使用工具管理我们的Redis&#xff0c;更加详细及深入的使用方法欢迎大家评论区讨论&#xff0c;我也和大家一起学习。 简介&#xff1a; Redis Desktop Manager (RDM) 是一个开源的图形化 Redis 数据库管理工具&#xff0c;…

解决 npm ERR! missing script: build 错误的方法

系列文章目录 文章目录 系列文章目录前言一、错误原因二、解决方法&#xff1a;三、注意事项&#xff1a;总结 前言 在使用 npm 进行前端项目构建时&#xff0c;有时会遇到错误信息 “npm ERR! missing script: build”&#xff0c;该错误通常发生在没有定义构建脚本时。本文将…

RocketMQ教程-安装和配置

Linux系统安装配置 64位操作系统&#xff0c;推荐 Linux/Unix/macOS 64位 JDK 1.8 Maven3.0 yum 安装jdk8 yum 安装maven 1.下载安装Apache RocketMQ RocketMQ 的安装包分为两种&#xff0c;二进制包和源码包。 点击这里 下载 Apache RocketMQ 5.1.3的源码包。你也可以从这…

STM32 Flash学习(一)

STM32 FLASH简介 不同型号的STM32&#xff0c;其Flash容量也不同。 MiniSTM32开发板选择的STM32F103RCT6的FLASH容量为256K字节&#xff0c;属于大容量产品。 STM32的闪存模块由&#xff1a;主存储器、信息块和闪存存储器接口寄存器等3部分组成。 主存储器&#xff0c;该部分…

交换机的学习和Vlan技术(第二十课)

交换机的学习和Vlan技术(第二十课) 一 冲突域 1 什么是冲突域 1)在一个网络范围内发送数据时会产生冲突的区域就是冲突域 2)冲突是以太网致命故障,导致信号冲突,数据损坏、丢失、数据传输慢 2 接口的双工模式 1、什么是冲突域 1)在一个网络范围内发送数据时会产生…

云安全攻防(一)之 云原生

前言 随着公有云和私有云的广泛部署&#xff0c;云计算基础设施成为企业部署新业务的首选。可以说&#xff0c;云计算已进入下半场&#xff0c;各大云计算服务商的厮杀日益激烈&#xff0c;新的概念也不断的层出不穷。近年来&#xff0c;云原生安全&#xff08;Cloud Native C…

挑战css基础面试题

挑战css基础面试题一&#xff0c;看看你能做出来吗 文章目录 前言一、盒模型二、如何实现一个最大的正方形三、文本一行水平居中&#xff0c;多行居左四、画一个三角形五、BFC理解六、两栏布局&#xff0c;左边固定&#xff0c;右边自适应&#xff0c;左右不重叠最后 前言 本片…

网络通信原理(第十八课)

网络通信原理(第十八课) 4.1 回顾 1.什么是TCP/IP 目前应用广泛的网络通信协议集 国际互联网上电脑相互通信的规则、约定。 2.主机通信的三要素 IP地址:用来标识一个节点的网络地址(区分网络中电脑身份的地址,如人有名字) 子网掩码:配合IP地址确定网络号 IP路由:网…