mybatis-plus工具学习笔记---[常用注解,条件构造器,插件使用](代码片段)

小智RE0 小智RE0     2023-02-27     654

关键词:

文章目录

近期也是计划学习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工具学习笔记---[基本概述,入门案例搭建,通用service接口使用](代码片段)

...查询总记录数4.2测试批量存储数据功能近期也是计划学习mybatis-plus,扩展知识;推荐官方文档食用学习–>https://baomidou.com/Mybatis-plus官方文档本次学习根据B站尚 查看详情

mybatis-plus工具学习笔记---[基本概述,入门案例搭建,通用service接口使用](代码片段)

...查询总记录数4.2测试批量存储数据功能近期也是计划学习mybatis-plus,扩展知识;推荐官方文档食用学习–>https://baomidou.com/Mybatis-plus官方文档本次学习根据B站尚 查看详情

mybatis-plus入门学习笔记(代码片段)

本文内容了解Mybatis-Plus整合Mybatis-Plus1、了解Mybatis-plus1.1、Mybatis-Plus介绍MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。愿景我们的愿景是成为MyBatis最好的搭档,就... 查看详情

mybatis-plus学习笔记(代码片段)

目录1.Mybatis-Plus简介1.1Mybatis-Plus介绍1.2代码以及文档1.3特性1.4框架结构1.5作者2.快速入门2.0准备工作2.1Mybatis整合Mybatis-Plus2.1.1原生Mybatis查询2.1.2使用Mybatis-Plus查询2.2Spring&Mybatis整合Mybatis-Plus2.3SpringBoot、Mybatis整合Mybatis 查看详情

数据库学习笔记第三弹——mysql常用的图形化管理辅助工具及相关问题(图文详解2022))(代码片段)

数据库学习笔记第三弹——MySQL常用的图形化管理辅助工具(图文详解2022)文章目录数据库学习笔记第三弹——MySQL常用的图形化管理辅助工具(图文详解2022)1.MySQL常用的图形化管理辅助工具1.1工具1MySQLWorkbench1.2... 查看详情

适合新手的12个mybatis-plus常用注解(代码片段)

摘要:MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。本文分享自华为云社区《那些年,我们一起学过的Mybatis-Plus的常用注解》,作者&#x... 查看详情

mybatis-plus-自动填充功能(学习笔记)(代码片段)

文章目录一、自动填充功能原理原理:二、使用步骤一共就三步,很简单:1:实体类2:配置类3:测试总结一、自动填充功能原理原理:实现元对象处理器接口:com.baomidou.mybatisplus.core.handlers.MetaObjectHandler二... 查看详情

[angularjs-学习笔记]工具篇

...着老师的步骤进行学习。   大漠老师关于开发工具的内容讲得比较快,对于其中前端常用的工具也只是简单了介绍了下。这里需要学员自己根据具体情况,选择自己需要的工具。同时,需要学员自己花额外的功夫来熟 查看详情

mybatisplus学习笔记(代码片段)

...章目录MyBatisPlus学习笔记简介特性框架结构快速使用引入mybatis-plus相关maven依赖引入mybatis-plus在springboot中的场景启动器项目中其他需要导入依赖创建表SQL语句项目结构一览项目配置配置MapperScan注解application.properties配置创建Entity(P... 查看详情

shell工具和脚本:学习笔记

...cn.github.io/。本篇为学习第二节课所做的笔记,主题是Shell工具和脚本,在这节课中,介绍了bash作为脚本语言的一些基础操作,以及几种最常用的shell工具。变量赋值:foo 查看详情

安全牛学习笔记tcpdump简介及常用命令实例

... tcpdump简介 tcpdump是一个运行在命令行下的嗅探工具。它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包。tcpdump是一个在BSD许可证下发布的自由软件。 tcpdump是非常强大的网络安全分析工... 查看详情

mybatis-plus-自动填充功能(学习笔记)(代码片段)

...以注入时间,也可以注入你自定义的东西):mybatis-plus,数据库的引入和配置等此处省略一共就三步,很简单:1:实体类@Data@TableName("sys_user")@AllArgsConstructor@NoArgsConstructorpublicclassUserim... 查看详情

java学习笔记6.3.4文件操作-path接口和files工具类

...、NIO.2概述(一)NIO.2定义与特点(二)NIO.2提供的接口与工具类三、Path接口与Paths类(一)Path接口定义(二)Path接口API文档(三)Path接口常用方法(四)Paths类API文档(五)Paths类常用方法(六)Path接口与Paths类案例演示四、Fi... 查看详情

linux~学习笔记目录索引

本篇文章是对自己学习Linux及在它的环境下部署工具的一个总结,以方便自己查阅,也给他人一个帮助,本文章同时会不断的更新,欢迎大家订阅!本目录包括的内容会包括linux基础命令,redis,mongodb,node.js,.netcore,kafka,rabbitmq,zookeep... 查看详情

visio学习笔记——visio的键盘快捷方式(代码片段)

...sio的键盘快捷方式常用热键常用对话框文本操作快速访问工具栏参考资料常用热键操作热键指针工具Ctrl+1文本工具Ctrl+2连接线Ctrl+3连接点工具Ctrl+Shift+1裁剪工具Ctrl+Shift+2文本块工具Ctrl+Shift+4组合所选的... 查看详情

学习笔记:javascriptbody常用事件

Window事件属性针对window对象触发的事件(应用到<body>标签):属性值描述onafterprintscript文档打印之后运行的脚本。onbeforeprintscript文档打印之前运行的脚本。onbeforeunloadscript文档卸载之前运行的脚本。onerrorscript在错误发生时... 查看详情

odi学习笔记2--odi产品架构

...记2--ODI产品架构ODI产品架构: ODI提供了以下几种管理工具:Designer用于定义数据转换逻辑,这是最常用的开发工具,大部分的开发任务,包括datastore的定义,interface(数据映射关系)和package(相当于workflow)的创建等,都是在De... 查看详情

13opensslssh脚本信息捕获学习笔记

...能的加密库libssl用于实现TLS/SSL的功能openssl多功能命令行工具openssl可用于:生成密钥、创建数字证书、手动加密解密数据加密解密技术常用的功能及算法:对称加密:(用于加密数据)算法:DES,3DES,AES,Blowfish,Twofish,RC6,CAST5工具:gpg 查看详情