Mybatis-plus工具学习笔记---[常用注解,条件构造器,插件使用]
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis-plus工具学习笔记---[常用注解,条件构造器,插件使用]相关的知识,希望对你有一定的参考价值。
文章目录
近期也是计划学习mybatis-plus,扩展知识;
推荐官方文档食用学习–>https://baomidou.com/
Mybatis-plus官方文档
本次学习根据B站尚硅谷教学视频:【尚硅谷】2022版MyBatisPlus教程(一套玩转mybatis-plus)
1.常用注解
1.1 @TableName
在之前学习的时候,注意到并没有指定操作哪个数据表,但是操作时它就会找到用户user
数据表;这是根据实体类User来判定找到的;
那么此时将数据库中的用户表名修改后,注意观察效果; 将
user 表名改为 t_user
找到之前编写的测试类MybatisPlusTest
运行测试方法;
此时发现程序报错数据表user
不存在;因为默认识别的是查询数据表user
,但是将数据表user
改名为t_user
了,也就无法匹配.
那么如何自动识别到要查询的数据表t_user
呢?
有两种方式:
- 首先,可以选择在
实体类User
处使用注解@TableName
来标注数据表的名称
再运行测试方法试试,可成功操作对应的数据表t_user
全局配置
- 当然,也可以选择第二种做法,在配置文件
application.yml
中进行配置数据表的识别;
先将刚才在实体类User写的注解
@TableName("t_user")
注释掉;
在application.yml
中配置mybatis的全局配置;对于项目使用的数据表公共前缀进行标注;
# 设置数据源类型,数据库信息;
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://127.0.0.1:3306/mybatis_plus_study_xiaozhi?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
#加入日志功能;
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#可配置mybatis的全局配置
global-config:
db-config:
table-prefix: t_
同样测试一下,也可以正常使用
1.2 @TableId
通过前面的学习,了解到mybatis-plus是默认将数据表中的id作为主键的,要是将数据表的字段id
改为uid
呢?是否还能正确识别到主键?
将数据表中的id修改为
uid
当然,实体类User的属性id也修改为
uid
在MybatisPlusTest
中执行测试的添加功能;
//测试新增功能;
@Test
public void startAdd()
User user = new User();
user.setName("小智");
user.setAge(22);
user.setEmail("xiaozhi@ceshi.com");
//新增数据;
//INSERT INTO user ( Uid, name, age, email ) VALUES ( ?, ?, ?, ? )
int insert = userMapper.insert(user);
//是否添加成功;
System.out.println("新增了" + insert + "条数据----------");
//立即获取到添加数据的主键Id;
System.out.println("立即获取新增的用户主键:" + user.getUid());
运行之,显而易见出现了sql错误.提示uid这个字段没有设定的默认值,即无法识别它的主键身份.
那么解决处理,可使用注解@TableId
来进行标注.
打开实体类User
;在属性uid
上使用注解;即可将属性uid
对应的字段uid
标识为主键;
@Data
@NoArgsConstructor
@AllArgsConstructor
//标注数据表名;
//@TableName("t_user")
public class User
@TableId
private Long uid;
private String name;
private Integer age;
private String email;
测试执行刚才的添加方法,数据成功存入;
键入注解TableId
,可看到value和type方法;这两个方法可操作的.
模拟场景,此时要是将用户User的属性
uid
改为id
. 而数据表的字段仍然是uid
,那么属性该如何识别到对应的字段uid
呢?
可使用value属性
进行标注即可;
再看看type
的功能; 可操作属性的策略;
先将数据表中的uid字段设置为自增;
首先测试一下添加数据方法;
运行之,发现uid还是默认的雪花算法生成的,并不是自增的;
那么实际上就需要用注解@TableId
的属性type
进行标注自增属性;
可以看注解@TableId
源码中的type()
方法返回值类型IdType
的源码,这是个枚举类,ok很容易找到这样一个方法来标注自增
.
在实体类User
设置即可;
@Data
@NoArgsConstructor
@AllArgsConstructor
//标注数据表名;
//@TableName("t_user")
public class User
//将属性对应的字段标注为主键;
//value属性可标注对应的字段;
@TableId(value = "uid",type = IdType.AUTO )
private Long id;
private String name;
private Integer age;
private String email;
测试执行添加数据的方法;OK,确实有自增效果了;
常见的主键设定策略:
- 默认的:
IdType.ASSIGN_ID
基于雪花算法的策略生成数据id,与数据库id是否设置自增无关 IdType.AUTO
使用数据库的自增策略,该类型请确保数据库设置了id自增,否则无效.
全局配置
当然,不使用注解也是可以的,在application.yml
中进行全局配置即可.使用参数id-type
配置主键生成策略即可.
# 设置数据源类型,数据库信息;
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://127.0.0.1:3306/mybatis_plus_study_xiaozhi?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
#加入日志功能;
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#可配置mybatis的全局配置
global-config:
db-config:
#设置实体类表的统一前缀;
table-prefix: t_
#可设置统一的主键生成策略;
id-type: auto
测试新增数据,可发现执行了自增策略.
1.3 雪花算法介绍
为应对数据规模的增长,需要分析访问压力和数据量
数据库的三种扩展方式:业务分库、主从复制,数据库分表。
关于数据库分表:
垂直分表:
水平分表
1.4 @TableField
首先模拟场景,数据表字段用下划线分隔,在实体类中属性用驼峰命名.
将user中的name
字段改为user_name
.
在实体类User中也进行修改.
执行测试方法;
执行sql时,名称字段还是user_name
,那么也就是说在mybatis-plus中有默认的下划线匹配对应驼峰
.
那要是不在实体类中使用驼峰命名法呢?
执行测试方法,
在执行sql时,无法识别到对应的字段
那么,即要不用驼峰命名,还要匹配对应字段,使用注解@TableField
即可.
执行测试方法;已正确识别到字段user_name.
1.5 @TableLogic
关于逻辑删除,也就是在代码逻辑上数据已经被删除,但是数据库中实际只是改变了数据的状态,数据并没有消除.\\
在数据表user中创建一个字段is_deleted
,表示该数据行是否删除的转态,默认为0
表示未删除,删除时修改该字段即可.
在实体类User中添加该属性.可用注解@TableLogic
表明逻辑删除.
现在测试执行删除方法;一次性删除3个.
但是注意到它执行的sql语句并不是delete
,而是update
更新数据,将字段is_deleted
由0变为了1.
当前的user数据表包含了22条数据,刚才逻辑删除3条.实际总数据应该是19条.
现在执行查询语句查看总数据量;
执行后,注意到总数据量为19条. 也就是说,逻辑删除已被认可.
执行的sql也用where来筛选is_deleted
为0的数据.
2. 条件构造器
![在这里插入图片描述](https://img-blog.csdnimg.cn/4f222f0bcb444022a1a0cd3a950269b6.png)
关于条件构造器的说明
Wrapper
:条件构造器的抽象类
AbstractWrapper
封装查询条件,可生成sql语句中的where条件.
QueryWrapper
封装查询条件
UpdateWrapper
封装更新条件
AbstractLambdaWrapper
,LambdaQueryWrapper
,LambdaUpdateWrapper
可使用Lambda语法
2.1 组装查询条件案例
先创建测试类MybatisPlusWrapperTest
;
import com.xiaozhi.mybatisplus.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @BelongsProject: mybatis-plus
* @BelongsPackage: com.xiaozhi.mybatisplus
* @Author: 信计1801 李智青
* @Date: 2022/7/1 20:27
* @Description: 条件构造器测试
*/
@SpringBootTest
public class MybatisPlusWrapperTest
//自动装配;
@Autowired
private UserMapper userMapper;
运行测试方法1,查询数据表中,name包含xaiozhi,年龄位于20-50之间,邮箱不为空的用户.
@Test
public void testOne()
//查询数据表中,name包含xaiozhi,年龄位于20-50之间,邮箱不为空的用户.
QueryWrapper<User> queryWrapper = new QueryWrapper();
queryWrapper.like("user_name", "xiaozhi")
.between("age", 20, 50)
.isNotNull("email");
//查询集合;
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
执行结果;
SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (user_name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
2.2 组装排序案例
运行测试方法2;查询用户信息,按年龄进行降序排序.年龄相同,则按照uid排序.
@Test
public void testTwo()
//查询用户信息,按年龄进行降序排序.年龄相同,则按照uid排序.
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("age")
.orderByAsc("uid");
//查询集合;
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
运行之;
SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 ORDER BY age DESC,uid ASC
2.3 组装删除条件案例
运行测试方法3:删除user_name
为空的数据
@Test
public void testThree()
//删除user_name不为空的数据
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.isNotNull("user_name");
int delete = userMapper.delete(queryWrapper);
System.out.println("删除了" + delete + "条数据");
运行之,实际是逻辑删除.
UPDATE t_user SET is_deleted=1 WHERE is_deleted=0 AND (user_name IS NOT NULL)
2.4 修改功能案例
测试方法4:修改数据:年龄大于20,用户名包含xiaozhi,或者邮箱为空的用户.
@Test
public void testFour()
//修改数据:年龄大于20,用户名包含xiaozhi,或者邮箱为空的用户.
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 20)
.like("user_name", "xiaozhi")
.or()
.isNull("email");
User user = new User();
user.setAge(20);
int update = userMapper.update(user, queryWrapper);
System.out.println("修改了" + update + "条数据");
运行之.
UPDATE t_user SET age=? WHERE is_deleted=0 AND (age > ? AND user_name LIKE ? OR email IS NULL)
2.5 条件的优先级设置
测试方法5:修改数据: 用户名包含xiaozhi,并且(年龄大于20岁或者邮箱为空的) 用户.
注意需要设置条件的优先级,不然写出来就和测试方法4差不多了.
@Test
public void testFive()
//修改数据: 用户名包含xiaozhi,并且(年龄大于20岁或者邮箱为空的) 用户.
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name", "xiaozhi")
.and(i -> i.gt("age", 20).or().isNull("email"));
User user = new User();
user.setAge(20);
int update = userMapper.update(user, queryWrapper);
System.out.println("修改了" + update + "条数据");
运行之,实际执行sql为:
UPDATE t_user SET age=? WHERE is_deleted=0 AND (user_name LIKE ? AND (age > ? OR email IS NULL))
2.6 组装select精确查询案例
测试方法6:查询用户的名称,年龄,邮箱;;
@Test
public void testSix()
//查询用户的名称,年龄,邮箱;;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("user_name", "age", "email");
//查询集合;
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
运行之,实际执行SQL为:
SELECT user_name,age,email FROM t_user WHERE is_deleted=0
2.7 组装子查询案例
测试方法7:查询uid小于100的用户.
@Test
public void testSeven()
//查询uid小于100的用户.
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("uid", "select uid from t_user where uid < 100");
//查询集合;
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
运行之,实际执行sql为:
SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (uid IN (select uid from t_user where uid < 100))
2.8 UpdateWrapper的修改功能案例
测试方法8: 修改数据: 用户名包含xiaozhi,并且(年龄大于20岁或者邮箱为空的) 用户.
@Test
public void testEight()
//修改数据: 用户名包含xiaozhi,并且(年龄大于20岁或者邮箱为空的) 用户.
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.like("user_name", "xiaozhi")
.and(i -> i.gt("age", "20").or().isNull("email"));
updateWrapper.set("user_name", "小智RE0").set("age", 22);
int update = userMapper.update(null, updateWrapper);
System.out.println("修改了" + update + "条数据");
运行之,实际运行SQL为:
UPDATE t_user SET user_name=?,age=? WHERE is_deleted=0 AND (user_name LIKE ? AND (age > ? OR email IS NULL))
2.9 模拟开发组装条件案例
编写一个模拟数据输入的案例
@Test
public void testNine()
//模拟前端输入数据;
String userName = "xiaozhi";
Integer ageStart = 22;
Integer ageEnd = 230;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//isNotBlank 判断字符串序列不是 null ,不是空白
if (StringUtils.isNotBlank(userName))
queryWrapper.like("user_name", userName);
if (ageStart != null)
queryWrapper.ge("age", ageStart);
if (ageEnd != null)
queryWrapper.le("age", ageEnd);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
运行之,实际运行SQL为:
SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (user_name LIKE ? AND age >= ? AND age <= ?)
2.10 使用Condition组装条件案例
测试方法10:
@Test
public void testTen()
//模拟前端输入数据;
String userName = "xiaozhi";
Integer ageStart = 20;
Integer ageEnd = 230;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//isNotBlank 判断字符串序列不是 null ,不是空白;
//这里用了布尔类型的参数condition作为判断先行条件;
queryWrapper.like(StringUtils.isNotBlank("user_name"), "user_name", userName)
.ge(ageStart != null, "age", ageStart)
.le(ageEnd != null, "age", ageEnd);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
运行之,实际执行sql为:
SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (user_name LIKE ? AND age >= ? AND age <= ?)
2.11 LambdaQueryWrapper案例
测试方法11:
@Test
public void testEleven()
//模拟前端输入数据;
String userName = "xiaozhi";
Integer ageStart = 20;
Integer ageEnd = 230;
LambdaQueryWrapper<User> queryWrapper = 以上是关于Mybatis-plus工具学习笔记---[常用注解,条件构造器,插件使用]的主要内容,如果未能解决你的问题,请参考以下文章
Mybatis-plus工具学习笔记---[基本概述,入门案例搭建,通用service接口使用]