医疗知识普及网站开发,网络营销教案,签订网站建设合同需要注意什么,相应式手机网站建设文章目录 1、尚硅谷-谷粒学院1.1、系统功能模块介绍1.2、系统开发方式 2、Mybatis-Plus2.1、什么是 MyBatis#xff1f;2.2、什么是Mybatis-Plus#xff1f;2.3、Mybatis-plus 的特性2.4、支持的数据库 3、Mybatis-Plus入门3.1、创建表和数据3.2、创建SpringBoot工程3.3、安装… 文章目录 1、尚硅谷-谷粒学院1.1、系统功能模块介绍1.2、系统开发方式 2、Mybatis-Plus2.1、什么是 MyBatis2.2、什么是Mybatis-Plus2.3、Mybatis-plus 的特性2.4、支持的数据库 3、Mybatis-Plus入门3.1、创建表和数据3.2、创建SpringBoot工程3.3、安装Mybatis-Plus3.3.1 问题pom依赖显示红色无法更新依赖3.3.2 安装Lombok插件 3.4 、配置application.properties3.5、实体类的编写3.6、创建Mapper接口3.7、测试3.8、Mybatis-plus的日志打印 4、Mybatis实现CRUD4.1、实现添加功能4.1.1、主键的生成策略自动增长UUIDRedis实现Mybatis-Plus中自带的策略 3.9.2、配置主键生成策略 4.2、实现更改数据4.2.1、自动填充 4.3、实现简单查询4.4、实现逻辑删除4.4.1、物理实现4.4.2、批量删除4.4.3、条件删除4.4.3、逻辑删除 5、乐观锁与悲观锁5.1、事务的隔离性5.2、乐观锁5.3、悲观锁5.4、配置乐观锁配置类 6、分页查询6.1、配置分页插件6.2、编写分页代码 7、性能分析插件8、实现复杂查询9、mybatis-plus实现自定义XML查询 1、尚硅谷-谷粒学院
1.1、系统功能模块介绍
后台系统1、讲师管理2、课程分类管理3、课程管理1.视频管理4、视频信息统计分析5、订单管理6、轮播图banner管理7、权限管理前台系统1、首页数据的显示2、讲师列表和详情3、课程列表和课程的详情1.课程详情2.课程观看3.课程评论4、登录和注册1.微信扫码登录5、微信扫码支付1.2、系统开发方式
前后端分离开发
全栈开发后端技术SpringBoot、SpringCloud、SpringSecurity、Redis、Maven、EasyExcel、Jwt、Oauth2
前端技术Vue、Element-UI、axios、node.js
其它技术阿里云OSS阿里云视频点播、阿里云短信服务、微信支付和登录、docker、jenkins、git2、Mybatis-Plus
2.1、什么是 MyBatis
https://mybatis.net.cn/getting-started.htmlMyBatis 是一款优秀的持久层框架它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJOPlain Old Java Objects普通老式 Java 对象为数据库中的记录。2.2、什么是Mybatis-Plus
https://baomidou.com/pages/24112f/MyBatis-Plus (opens new window)简称 MP是一个 MyBatis (opens new window)的增强工具在 MyBatis 的基础上只做增强不做改变为简化开发、提高效率而生。2.3、Mybatis-plus 的特性
无侵入只做增强不做改变引入它不会对现有工程产生影响如丝般顺滑损耗小启动即会自动注入基本 CURD性能基本无损耗直接面向对象操作强大的 CRUD 操作内置通用 Mapper、通用 Service仅仅通过少量配置即可实现单表大部分 CRUD 操作更有强大的条件构造器满足各类使用需求支持 Lambda 形式调用通过 Lambda 表达式方便的编写各类查询条件无需再担心字段写错支持主键自动生成支持多达 4 种主键策略内含分布式唯一 ID 生成器 - Sequence可自由配置完美解决主键问题支持 ActiveRecord 模式支持 ActiveRecord 形式调用实体类只需继承 Model 类即可进行强大的 CRUD 操作支持自定义全局通用操作支持全局通用方法注入 Write once, use anywhere 内置代码生成器采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码支持模板引擎更有超多自定义配置等您来使用内置分页插件基于 MyBatis 物理分页开发者无需关心具体操作配置好插件之后写分页等同于普通 List 查询分页插件支持多种数据库支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库内置性能分析插件可输出 SQL 语句以及其执行时间建议开发测试时启用该功能能快速揪出慢查询内置全局拦截插件提供全表 delete 、 update 操作智能分析阻断也可自定义拦截规则预防误操作
2.4、支持的数据库
MySQLOracleDB2H2HSQLSQLitePostgreSQLSQLServerPhoenixGauss ClickHouseSybaseOceanBaseFirebirdCubridGoldilockscsiidb
达梦数据库虚谷数据库人大金仓数据库南大通用(华库)数据库南大通用数据库神通数据库瀚高数据库3、Mybatis-Plus入门
3.1、创建表和数据
表和数据的脚本来源于Mybatis-plus的官网来自快速开始。
#创建表
DROP TABLE IF EXISTS user;
CREATE TABLE user
(id BIGINT(20) NOT NULL COMMENT 主键ID,name VARCHAR(30) NULL DEFAULT NULL COMMENT 姓名,age INT(11) NULL DEFAULT NULL COMMENT 年龄,email VARCHAR(50) NULL DEFAULT NULL COMMENT 邮箱,PRIMARY KEY (id)
);DELETE FROM user;
#插入数据
INSERT INTO user (id, name, age, email) VALUES
(1, Jone, 18, test1baomidou.com),
(2, Jack, 20, test2baomidou.com),
(3, Tom, 28, test3baomidou.com),
(4, Sandy, 21, test4baomidou.com),
(5, Billie, 24, test5baomidou.com);3.2、创建SpringBoot工程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87gCXMkO-1690788257982)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805092526643.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-akmT3Fgl-1690788257987)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805092625620.png)] 视频中使用的版本是2.2.1最好选择稳定版本不要选择最新的版本这里我选择2.7.2版本的SpringBoot是稳定版 3.3、安装Mybatis-Plus
在pom文件中写入以下的依赖。
如果出现依赖无法加载的情况请更新maven的镜像库阿里云的比较好。
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency!--Mybatis-plus--dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.2/version/dependency
!--lombok --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.12/version/dependency
!--数据库连接包 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.19/version/dependency/dependencies3.3.1 问题pom依赖显示红色无法更新依赖
提示信息
No valid Maven installation found. Either set the home directory in the configuration dialog or set the M2_HOME environment variable on your system.没有找到 可用的maven 安装设置。要么在配置对话框中设置主home目录或者在你的系统上设置M2_HOME环境变量。Either...or... 要么...要么...configuration 配置dialog 对话原因
IDEA的Maven地址设置出错找不到指定的maven路径解决方案在IDEA中配置好Maven的位置包括setting.xml和repository的位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oTHY01b3-1690788257992)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805094250837.png)]
https://blog.csdn.net/Julycaka/article/details/831856213.3.2 安装Lombok插件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RP8acKdP-1690788257997)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805095431661.png)]
插件里面搜索Lombok安装3.4 、配置application.properties
application.yaml或者application.properties都可以src/ main/ resources
spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver
spring.datasource.urljdbc:mysql://localhost:3306/mybatisstudy?serverTimezoneGMT
spring.datasource.usernameroot
spring.datasource.passwordli14736067683.5、实体类的编写
使用Lombok减少代码量。
Data会给该类的所有私有属性自动添加Get和Set方法。 AllArgsConstructor是有参,NoArgsConstructor是无参 实体类User
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dtCjW2zE-1690788258002)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805100429878.png)]
3.6、创建Mapper接口
使接口类继承BaseMapper
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AuZulL2T-1690788258006)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805100834752.png)]
继承之后按住Control点击BaseMapper这个类就可以看到里面自动生成的方法。
然后我们还需要对SpringBoot的启动类添加一个MapperScan的注解注解的参数为实际放置Mapper的包的路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IThr9Op4-1690788258011)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805101028092.png)]
Repository是sping注解需要配合MapperScan使用Mapper是mybatis注解可以单独使用3.7、测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XnTmiHZN-1690788258016)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805101641707.png)] 如果注入的userMapper出现红色波浪线提示则可以在userMapper类中声明Repository或者Service将这个类声明为一个Bean对象 /*** discription 查看数据库中user表的数据* author Macieserenity* updateTime 2022/8/5 11:33 * return * throws */Testvoid contextLoads() {//查询user中的所有数据ListUser usersuserMapper.selectList(null);System.out.println(查询);System.out.println(usersusers);}运行test类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-99MzZPU7-1690788258020)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805101921958.png)]
[User(id1, nameJone, age18, emailtest1baomidou.com),
User(id2, nameJack, age20, emailtest2baomidou.com),
User(id3, nameTom, age28, emailtest3baomidou.com),
User(id4, nameSandy, age21, emailtest4baomidou.com),
User(id5, nameBillie, age24, emailtest5baomidou.com)]3.8、Mybatis-plus的日志打印
在application.properties文件中加入
mybatis-plus.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CGfgsrdU-1690788258025)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805112630879.png)] 使用select * 的话会降低效率 https://blog.csdn.net/jiangchao858/article/details/1156763714、Mybatis实现CRUD
4.1、实现添加功能
/*** discription 往数据库中添加一条记录* author Macieserenity* updateTime 2022/8/5 11:32 * return * throws */Testvoid addUser(){User user new User();user.setAge(18);user.setEmail(hello123.com);user.setName(makabaka);int resultuserMapper.insert(user);System.out.println(插入);System.out.println(insertresult);}[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JmxCaPgb-1690788258030)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805113608121.png)]
可以看到我们没有设置User 的id属性但是查看日志可以看到Mybatis-Plus自动为我们生成了19位Long主键的值。
4.1.1、主键的生成策略
注意3.5版的mybatis-plus 已经将ID_WORKER改名叫ASSIGN_ID了自动增长
Auto_increment缺点很难进行分表分库存储要进行分表存储时需要得到上一张表的长度在此长度上1作为当前表的起始ID
UUID
每次生成一个随机且唯一的值缺点无法进行排序
Redis实现
redis生成ID由于redis是单线程的可以生成全局唯一的ID可以用redis的原子操作INCR和INCRBY来实现。Mybatis-Plus中自带的策略
雪花算法
生成一个long型的ID使用41bit作为毫秒数10bit作为机器的ID(5个bit是数据中心5个bit是机器的ID)12bit作为毫秒内的流水号意味着每个节点在每毫秒可以产生4096个ID。
最后一个是符号位永远是0。3.9.2、配置主键生成策略
在实体类的id属性上增加一个
TableId(typeIdType.AUTO)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RYN4kO69-1690788258034)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805114937801.png)] 注意3.5版的mybatis-plus 已经将ID_WORKER和ID_WORKER_STR改名叫ASSIGN_ID了 然后按住control键点击AUTO进入查看里面的策略
AUTO主键字段自增
实体类的主键字段的注解 TableId(type IdType.AUTO)
数据表对应的字段一定也要设置成自增
如果只加了注解但没有将数据表对应的主键字段设置为自增则将会出现如下的异常NONE未设置主键
由于每一张数据表都是有主键的因此几乎没有添加该注解的必要。INPUT需要开发者手动赋值
INPUT 如果开发者没有手动赋值则数据库通过设置自增方式给主键赋值(MP不介入主键生成)同样地如果数据库也没有设置自增则会抛出异常如果开发者手动赋值则直接存入该值。ASSIGN_IDMyBatis-Plus 自动赋值
ASSIGN_ID 如果用户或开发者没有为主键赋值则由 MyBatis-Plus 采用 snowflake 算法(也被称为雪花算法)为主键字段分配一个ID这个 ID 可以是 Number(Long) 类型也可以是 String 类型。ASSIGN_UUIDMyBatis-Plus 分配 UUID必须是 String 类型
ASSIGN_UUID 的用法与 ASSIGN_ID 类似可以表示更长的唯一的 ID但其主键的数据类型必须是 String由 MyBatis-Plus 自动生成 UUID 进行赋值雪花算法snowflake是Twitter开源的分布式ID生成算法结果是一个long型的ID。其核心思想是使用41bit作为 毫秒数10bit作为机器的ID5个bit是数据中心5个bit的机器ID12bit作为毫秒内的流水号意味 着每个节点在每毫秒可以产生 4096 个 ID最后还有一个符号位永远是0。可以保证几乎全球唯 一 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zPhKOrAh-1690788258039)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805115030254.png)]
参考文章
https://blog.csdn.net/m0_61961937/article/details/126048049
https://blog.csdn.net/qq_41775769/article/details/1230450894.2、实现更改数据
/*** author Macieserenity* br/* Update 更新数据*/
Test
void updateUser(){User user new User();user.setId(2L);user.setAge(18);user.setEmail(hello123Update.com);user.setName(makabaka);int resultuserMapper.updateById(user);System.out.println(update resultresult);
}[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-REtTAH1D-1690788258044)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805132726484.png)]
4.2.1、自动填充
往表中添加两个字段
#在表user中添加create_time date类型 和 update_time date类型两个字段.mysql alter table user add create_time date;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0mysql alter table user add update_time date;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0在实体类中添加对应的属性
注意命名的特点
在java中使用驼峰式命名createTime
在数据库中不区分大小写所以用下划线分割两个单词create_time手动填充方式
Test
void addUserDate(){User user new User();user.setAge(22);user.setEmail(hello123.comMakabaka);user.setName(makabakaUpdateDate);//手动添加时间user.setCreateTime(new Date());user.setUpdateTime(new Date());int resultuserMapper.insert(user);System.out.println(插入);System.out.println(insertresult);
}Mybatis-plus自动填充
不需要手动set值使用mybatis-plus框架的方式
//第一步在实体类里面使用注解声明为自动填充[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xD8lgqet-1690788258048)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805134140700.png)]
或者可以把updateTime的自动填充类型设置为
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-elJU9x49-1690788258053)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805134229981.png)]
这样在插入和更新的时候就会自动进行填充。
//第二步创建类实现implement接口MetaObjectHandler
//实现insertFill和updateFill两个方法
//在类上添加Component声明为Spring组件交由Spring管理//目录
package com.study.mybatisplusstudy.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;import java.util.Date;
/*** className: MyMetaObjectHandlerbr/* author: MacieSerenitybr/* date: 2022-08-05 13:44br/**/
public class MyMetaObjectHandler implements MetaObjectHandler {/*** discription 在insert语句执行时对设定的属性进行自动填充 br/* author Macieserenity br/ * param: metaObject br/* updateTime 2022/8/5 13:55 br/* return br/* throws br/*/Overridepublic void insertFill(MetaObject metaObject) {//第一个参数数据库中需要自动填充的字段取Java实体类的属性名称作为参数//第二个参数需要填充的数据//第三个参数源数据this.setFieldValByName(createTime,new Date(),metaObject);this.setFieldValByName(updateTime,new Date(),metaObject);}/*** discription 在进行数据的更新时进行数据的自动填充 br/* author Macieserenity br/ * param: metaObject br/* updateTime 2022/8/5 13:58 br/* return br/* throws br/*/Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName(updateTime,new Date(),metaObject);}
}然后使用test类进行测试
//
Test
void addUserDate(){User user new User();user.setAge(22);user.setEmail(hello123.comMakabaka);user.setName(makabakaUpdateDate);int resultuserMapper.insert(user);System.out.println(插入);System.out.println(insertresult);
}[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8O6NO8eh-1690788258058)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805141705861.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dDjCKTi3-1690788258063)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805141641874.png)]
4.3、实现简单查询
/*** discription 查看数据库中user表的数据* author Macieserenity* updateTime 2022/8/5 11:33 * return * throws */Testvoid contextLoads() {//查询user中的所有数据ListUser usersuserMapper.selectList(null);System.out.println(查询);System.out.println(usersusers);}Test
void selectUserById(){//通过ID查询User userById userMapper.selectById(1555455304972189698L);//通过ID批量查询ListUser users1 userMapper.selectBatchIds(Arrays.asList(1555455304972189698L, 1555437406157303809L, 1555436878589341698L));System.out.println(userByIduserById);System.out.println(users1users1);
}[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9DoXYCgp-1690788258068)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805155131130.png)]
根据Map实现条件查询
Test
void selectUserByMap(){HashMapString,Object mapnew HashMap();map.put(name,Helen);map.put(age,18);ListUser users userMapper.selectByMap(map);users.forEach(System.out::println);
}[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gk2mS6c7-1690788258073)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805155545943.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qOCD7kII-1690788258079)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805155557911.png)]
4.4、实现逻辑删除
4.4.1、物理实现
/*** discription 删除ID为1555396057806725121的用户 br/* author Macieserenity br/ br/* updateTime 2022/8/5 14:44 br/* return br/* throws br/*/
Test
void deleteUser(){User user new User();user.setId(1555396057806725121L);int result userMapper.deleteById(user);System.out.println(delete resultresult);
}[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3VrFHTDw-1690788258084)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805144411160.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cjNu5pYX-1690788258089)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805144435406.png)]
4.4.2、批量删除
同时删除多条记录Test
void deleteMultiple(){
int result userMapper.deleteBatchIds(Arrays.asList(1,2));
}4.4.3、条件删除
Test
void deleteByMap(){HashMapString,Object mapnew HashMap();map.put(name,Helen);map.put(age,18);int result userMapper.deleteByMap(map);
}根据map进行条件删除
4.4.3、逻辑删除
原理在表中做一个标志位更改标志位select时将该标志位标记为已删除的记录不可见或者跳过完成逻辑删除。该插件默认0没有删除1删除
可以到配置文件中进行更改
mybatis-plus.global-config.db-confg.logic-delete-value1
mybatis-plus.global-config.db-confg.logic-no-delete-value0第一步在数据库中添加deleted字段
alter table user drop column deleted;
alter table user add deleted int default 0;第二步在实体类对应的属性上添加注解
TableLogic
TableField(fillFieldFill.INSERT)需要增加的语句
//---User.java
TableLogic
TableField(fill FieldFill.INSERT)
private Integer deleted;//---MyMetaObjectHandler.java
this.setFieldValByName(deleted,1,metaObject);加上逻辑删除的插件
mybatis-plus 3.5版本及以上就不需要配置插件了
只需要在实体类中使用对应的组件和创建数据库时添加对应的字段即可
详情
https://blog.csdn.net/qq_57581439/article/details/124050671第三步测试
Test
void logicDelete(){int i userMapper.deleteById(1555437406157303809L);System.out.println(i1?删除了:删除了但是没完全删除);
}[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-REcjlvqz-1690788258094)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805165252612.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YxdfpN2h-1690788258099)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805165403779.png)]
此时我们进行查询
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1r8iIFSu-1690788258105)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805165515044.png)]
查看日志文件可以知道自动为我们过滤了被逻辑删除的查询
//注意
//一旦加上了逻辑删除插件mybatis-plus将无法查询到被逻辑删除的数据即便加了deleted1
//只能使用xml文件自定义一个SQL语句进行查询。5、乐观锁与悲观锁
5.1、事务的隔离性
是为了解决 丢失更新 问题事务的隔离性脏读 不可重复读
不可重复读和幻读是初学者不易分清的概念总的来说解决不可重复读的方法是 锁行解决幻读的方式是 锁表。事物的隔离性
#读未提交read uncomitted最低的隔离级别什么是读未提交事务A可以读取到事务B未提交的数据。这种隔离级别存在的问题就是Dirty Read 脏读现象读到了脏数据例如有事务A和事务B都有以下DML语句更新查询更新查询...假设事务A和B并行执行且我们这种隔离级别都试了理论上的大多数的数据库隔离级别都是在 第二个读已提交 级别之后的。#读已提交read committed什么是读已提交事务A只能读到事务B提交之后的数据。这种隔离级别解决了脏读现象。不可重复读数据。事务在开启之后第一次和第二次读取的数据可能不会相同所以不可重复读。这种隔离级别是比较真实的数据每次读取的都是绝对的真实数据。例如事务A和事务B 两个事务中都有多条DML语句如下插入查询插入查询...当事务A和事务B并行执行时我们假设事务A在事务B执行到一半时提交了那么事务B的第二次读取就能读取到事务A已经提交的数据而第一次读取到的也还是事务A未更改之前的数据。只能读取到已经提交的数据oracle数据库默认的隔离级别就是 read committed#可重复读repeatable read什么是可重复读事务开启之后无论多久在事务A中读取到的数据都是一致的即使事务B已经将数据修改且提交了但是事务A读取到的数据还是不会发生改变这就是可重复读。解决了不可重复读数据的问题。但是会产生幻影读每一次读取的数据都是幻象不够真实。#序列化/串行化serializable (最高的隔离级别)什么是序列化是最高级别的隔离效率最低解决了所有的问题。这种隔离级别表示事务排队不能并发。synchronize线程同步事务同步每一次读取到的数据都是最真实的且效率最低。5.2、乐观锁
取出记录时记录版本号执行事务完毕后确定当前数据版本号是不是读取时候的版本修改后版本相同时更改版本号若版本号不同则回滚。异步支持并发
场景抢票系统只能有一个人能抢到5.3、悲观锁
串行同步阻塞5.4、配置乐观锁
在表中添加一个version字段作为乐观锁的版本字段
alter table user add version int;然后在实体类中添加version注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-koHiv39X-1690788258110)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805152722808.png)] 这里TableField跟上面一样插入时赋值为1 配置类
配置类是springBoot提供的一个专门用于配置的类使用Configuration注解声明为的是避免启动类中有过多的配置方法可以讲这些配置方法专门写入一个配置类中方便管理。
配置一个乐观锁插件
我们新建一个包叫做config里面存我们的配置类我们可以把刚才写在主入口函数上的MapperScan一起写到该配置类中然后将从官网找到乐观锁插件记得要比对自己的Mybatis-Plus的版本号它不同版本的插件好像有略微不同
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jmH6AcGH-1690788258115)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805153308864.png)]
//可以从官方网站copy下来
https://baomidou.com/pages/0d93c0/#optimisticlockerinnerinterceptorBean
public MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;
}此时我们编写一个测试类
注意必须先查再改
Test
void testVersion(){User user userMapper.selectById(1555455304972189698L);user.setAge(2000);userMapper.updateById(user);
}然后我们可以通过select数据库中的数据查看执行前和执行后的数据变化
可以看到version变化了age变成了2000
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HnEcm3sK-1690788258120)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805154515922.png)]
6、分页查询
与pageHelper类似6.1、配置分页插件
https://baomidou.com/pages/97710a/#%E5%B1%9E%E6%80%A7%E4%BB%8B%E7%BB%8D//以下代码写在配置类当中
Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());//增加一行 添加分页插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor());return interceptor;
}6.2、编写分页代码
new page对象传入两个参数
当前页
页面大小
然后调用Mybatis-Plus的方法进行分页。
Testvoid pagenation(){/*** 创建page对象* 传入两个参数当前页和每页显示记录条数*/PageUser pagenew Page(1,3);/*** 使用方法* 调用Mybatis-plus的分页查询方法进行底层的封装* 将数据封装到page对象里面*/userMapper.selectPage(page,null);/*** 获取分页的当前页*/System.out.println(page.getCurrent());/*** 获取每页的list数据*/System.out.println(page.getRecords());/*** 获取表中的总记录数*/System.out.println(page.getTotal());/*** 获取总页数*/System.out.println(page.getPages());/*** 是否有下一页*/System.out.println(page.hasNext());/*** 是否有上一页*/System.out.println(page.hasPrevious());
}[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D48iUGqe-1690788258125)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220805162524854.png)] Bean
public MybatisPlusInterceptor pageinationinterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();// 如果用了分页插件注意先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor// 用了分页插件必须设置 MybatisConfiguration#useDeprecatedExecutor falseinterceptor.addInnerInterceptor(new PaginationInnerInterceptor());return interceptor;
}
查找问题的时候看到的虽然跟我这个问题不是特别有关系但是可能以后有用https://blog.csdn.net/m0_49513507/article/details/1242004587、性能分析插件 /**
* dev 开发环境
* test 测试环境
* prod 生产环境
*/
//该插件 3.2.0 以上版本移除推荐使用第三方扩展 执行SQL分析打印 功能
Bean
Profile({dev,test})
public PerformanceInterceptor performanceInterceptor(){PerformanceInterceptor performanceInterceptornew PerformanceInterceptor();performanceInterceptor.setMaxTime(100);//超过100msSQL语句不执行performanceInterceptor.setFormat(true);return performanceInterceptor;
}配置spring的环境
在application.properties中添加
spring.profiles.activedev8、实现复杂查询
Test
void testWrapper(){QueryWrapperUser wrappernew QueryWrapper();//通过QueryWrapper设置条件//ge,gt,le,lt 大于等于、大于、小于等于、小于//示例查询age30的wrapper.ge(age,10);//eq 等于 ne 不等于wrapper.ne(name,lucy);//betweenwrapper.between(age,20,30);//like 模糊查询wrapper.like(email,test);//oderByDescwrapper.orderByDesc(id);//last 拼接到语句最后 尽量不要用wrapper.last(limit 1);//指定要查询的列wrapper.select(id,name);ListUser users userMapper.selectList(wrapper);System.out.println(users);}[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hdEUo5zi-1690788258130)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220806100639243.png)]
9、mybatis-plus实现自定义XML查询
首先写一个Mapper类继承BaseMapper类
项目目录结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r0pWlAik-1690788258134)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220806111820748.png)]
package com.study.mybatisplusstudy.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.study.mybatisplusstudy.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;/*** className: UserMapper* Author: yeyulemon* Date: 2022-08-05 10:06**/
Repository
Mapper
public interface UserMapper extends BaseMapperUser {
// 也可以不用配置XML直接使用注解的方式实现
// Select(select * from user where id #{id})
// User findSomeone(Param(id) Long Id);//声明一个方法findSomeoneUser findSomeone(Param(id) Long Id);
}一定要记得在配置类或者是启动类加伤MapperScan扫描mapper
Configuration
MapperScan(com/study/mybatisplusstudy/mapper)
public class MyConfig {...
}然后我们在resources文件夹下创建一个文件夹来存储我们的xml文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ur46o7sn-1690788258139)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220806111701212.png)]
还有就是在application.properties文件中配置好对应的mapper.xml的位置用于扫描mapper
#确定位置#
mybatis-plus.mapper-locationsclasspath:/mybatisMapper/*Mapper.xml
#日志#
mybatis-plus.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.study.mybatisplusstudy.mapper.UserMapperresultMap iduserMap typecom.study.mybatisplusstudy.entity.Userid columnid propertyid /result columnname propertyname /result columnage propertyage /result columnemail propertyemail /result columncreate_time propertycreateTime /result columnupdate_time propertyupdateTime /result columnversion propertyversion /result columndeleted propertydeleted //resultMapselect idfindSomeone resultMapuserMapselect id,name,age,email,create_time,update_time,version,deleted from user where id ${id};/select
/mapper我们在xmlwen文件中一定要声明mapper的namespace指定为刚刚创建的接口类路径一定要选择正确
然后是如果是查询语句我们需要写一个对应的resultMap来指定查询结果中实体类与数据库中数据的对应关系
例如数据库中查询出来的列名叫做create_time找到实体类中对应的名称一般是驼峰命名法crateTime进行绑定
如上resultMap所示。
绑定完成之后要在对应的select语句后面使用resultMap指定返回值的绑定关系。
之后我们编写测试类来测试
/*** discription 自定义XML方式实现SQL查询 br/* author Macieserenity br/ br/* updateTime 2022/8/6 11:23 br/* return br/* throws br/*/
Test
void testXmlSQL(){User selectUser userMapper.findSomeone(1L);System.out.println(selectUser);
}不同于默认配置这里的SQL日志打印出来之后是直接带着数据的没有进行prepare预处理
预处理 where id ?
这里没有进行预处理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KiOY7g10-1690788258143)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220806112538208.png)]
原因是因为我们在xml中的select语句中使用的$符号而不是#号此时我们将xml文件中的select语句进行修改
select idfindSomeone resultMapuserMapselect id,name,age,email,create_time,update_time,version,deleted from user where id #{id};
/select注意这里我们之前使用的是id ${id} 此时我们将其改为 where id #{id}再次执行测试类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iseyszhr-1690788258148)(%E5%B0%9A%E7%A1%85%E8%B0%B7-%E8%B0%B7%E7%B2%92%E5%AD%A6%E9%99%A2%E9%A1%B9%E7%9B%AE.assets/image-20220806112844194.png)]
可以看到SQL语句正常的执行了预处理其参数变成了 ?
返回的数据
User(id1, nameJone, age18, emailtest1baomidou.com, createTimenull, updateTimenull, versionnull, deleted0)