MyBatisPlus Study Notes
文章目录
- 1 MyBatisPlus概述
- 1.1 MyBatis介绍
- 1.2 MyBatisPlus特性
- 2 标准数据层开发
- 2.1 MyBatisPlus的CRUD操作API
- 2.2 分页功能接口实现
- 2.2.1 config(配置层)拦截器实现
- 2.2.2 Dao(Mapper)数据访问层(CRUD)操作
- 2.2.3 Junit单元测试进行测试
- 2.3 开启MyBatisPlus日志
- 2.4 取消初始化spring日志打印
- 2.5 取消SpringBoot启动banner图标、关闭mybatisplus启动图标
- 3 MyBatisPlus DQL
- 3.1 条件查询API
- 3.2 条件查询
- 3.2.1 方式一:按条件查询(常规格式)
- 3.2.2 方式二:按条件查询(lambda格式)
- 3.3 MyBatisPlus中null值判断
- 3.4 批量(Batch)操作
- 3.5 查询投影(聚合查询)【查询字段、分组、分页】
- 3.6 字段映射与表名映射
- 4 DML编程控制
- 4.1 id生成策略控制(Insert)
- 4.2 逻辑删除(Delete/Update)
- 4.2.1 数据库表中添加逻辑删除字段
- 4.2.2 实体类中添加对应字段,并设定当前字段为逻辑删除标记字段
- 5 乐观锁(Update)
1 MyBatisPlus概述
1.1 MyBatis介绍
- MyBatisPlus(简称MP)基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率
- MyBatisPlus官网
1.2 MyBatisPlus特性
- 无侵入:只做增强不做改变,不会对现有工程产生影响
- 强大的 CRUD 操作:内置通用 Mapper,少量配置即可实现单表CRUD 操作
- 支持 Lambda:编写查询条件无需担心字段写错
- 支持主键自动生成
- 内置分页插件
- ……
2 标准数据层开发
2.1 MyBatisPlus的CRUD操作API

2.2 分页功能接口实现

2.2.1 config(配置层)拦截器实现
此处拦截SQL语句,目的是为了拼接,分页条件
@Configuration
public class MpConfig {@Beanpublic MybatisPlusInterceptor mpInterceptor(){//1.定义Mp拦截器 ,创建MybatisPlusInterceptor拦截器对象MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();//2.添加具体的拦截器、添加分页拦截器mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());return mpInterceptor;}
}
2.2.2 Dao(Mapper)数据访问层(CRUD)操作
实现BaseMapper<>接口
@Mapper
public interface UserDao extends BaseMapper<User> {
}
2.2.3 Junit单元测试进行测试
@Testpublic void testPage() {IPage<User> page = new Page(2, 5);// 分页构造器:设置 当前第几页 一页多少条IPage<User> pageResult = userDao.selectPage(page, null);System.out.println(JSON.toJSONString(page));System.out.println("数据列表" + JSON.toJSONString(pageResult.getRecords()));System.out.println("当前页码" + pageResult.getCurrent());System.out.println("每页条数" + pageResult.getSize());System.out.println("总记录数" + pageResult.getTotal());System.out.println("总页数" + pageResult.getPages());}
}
2.3 开启MyBatisPlus日志
# 开启mp的日志(输出到控制台)
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
2.4 取消初始化spring日志打印
做法:在resources下新建ogback.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration></configuration>
2.5 取消SpringBoot启动banner图标、关闭mybatisplus启动图标
spring:main:banner-mode: off # 关闭SpringBoot启动图标(banner)
# mybatis-plus日志控制台输出
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:banner: off # 关闭mybatisplus启动图标
3 MyBatisPlus DQL
3.1 条件查询API

3.2 条件查询
3.2.1 方式一:按条件查询(常规格式)
//方式一:按条件查询@Testpublic void test1(){// select * from user where age >= 18 and age < 65QueryWrapper<User> qw = new QueryWrapper<>();qw.ge("age",18);qw.lt("age",65);List<User> userList = userDao.selectList(qw);System.out.println(JSON.toJSONString(userList)); //[{"age":28,"id":5,"name":"snake","password":"123456","tel":"12345678910"},{"age":22,"id":6,"name":"张益达","password":"123456","tel":"12345678910"}]/*System.out.println(userList);不进行JSON转换输出[User(id=5, name=snake, password=123456, age=28, tel=12345678910), User(id=6, name=张益达, password=123456, age=22, tel=12345678910)]* */}
3.2.2 方式二:按条件查询(lambda格式)
查阅源码优化全局变量处声明对象操作
3.2.2.1全局变量声明
LambdaQueryWrapper<User> userLambdaQueryWrapper = Wrappers.lambdaQuery();//lambdaQuery 可用屏蔽底层的具体实现,未来会有变化上层代码无需过多的调整。而且不用new对象减少内存@Autowiredprivate UserDao userDao;
3.2.2.2 select * from user where age >= 18 and age < 65
| 传统语法 | MyBatisPlus语法 | 说明 |
|---|---|---|
| < | lt | less than |
| <= | le | less equal |
| > | gt | greater than |
| >= | ge | greater equal |
| = | eq | equal |
| between and | 范围 | |
| like | 模糊查询 | |
| in | 在in之后的列表中的值,多选一 |
//lambda格式@Testpublic void test2(){// select * from user where age >= 18 and age < 65//LambdaQueryWrapper<User> userLambdaQueryWrapper1 = new LambdaQueryWrapper<>();// LambdaQueryWrapper<User> userLambdaQueryWrapper = Wrappers.lambdaQuery();userLambdaQueryWrapper.ge(User::getAge,18).lt(User::getAge,65);List<User> userList = userDao.selectList(userLambdaQueryWrapper);System.out.println(JSON.toJSONString(userList));System.out.println("=================");System.out.println(userList);}
// 等于@Testpublic void test3(){//select * from user where name = "tom"userLambdaQueryWrapper.eq(User::getName,"tom");List<User> userList = userDao.selectList(userLambdaQueryWrapper);System.out.println(JSON.toJSONString(userList));}
3.3 MyBatisPlus中null值判断
/*** null值判断* 判断 字段值是否为null 不为null才拼接查询条件*/@Testpublic void test31(){//模拟前端传的参数//select * from user where name = nullUser user = new User();/* if (user.getName()!=null){userLambdaQueryWrapper.eq(User::getName,user.getName());}健壮性判断*/userLambdaQueryWrapper.eq(user.getName()!= null,User::getName,user.getName());//此处user.getName()为空,User::getName与user.getName()作对比,// 即 在数据库实体类中的name属性="null" 做判断条件List<User> userList = userDao.selectList(userLambdaQueryWrapper);System.out.println(JSON.toJSONString(userList));}
// like模糊查询@Testpublic void test4(){//select * from user where name like "j%"userLambdaQueryWrapper.like(User::getName,"j");List<User> list = userDao.selectList(userLambdaQueryWrapper);System.out.println(list);}
/*** between*/@Testpublic void test5(){//select * from user where age between 16 and 28userLambdaQueryWrapper.between(User::getAge, 16, 28);List<User> list = userDao.selectList(userLambdaQueryWrapper);System.out.println(list);}
/*** in*/@Testpublic void test6(){//select * from user where id in (1,2,3)List<Integer> inList = Arrays.asList(1, 2, 3);userLambdaQueryWrapper.in(User::getId, inList);List<User> list = userDao.selectList(userLambdaQueryWrapper);System.out.println(list);}
3.4 批量(Batch)操作
/*** 根据id列表批量查询*/@Testpublic void test1(){List<Integer> ids = Arrays.asList(1, 2, 3);//将一个变长参数或者数组转换成ListList<User> userList = userDao.selectBatchIds(ids);System.out.println(userList);}
/*** 根据id列表批量删除*/@Testpublic void test2(){List<Integer> ids = Arrays.asList(1, 2, 3);int count = userDao.deleteBatchIds(ids);System.out.println(count);}
3.5 查询投影(聚合查询)【查询字段、分组、分页】
/*** 聚合查询一般用: selectMaps*/@Testpublic void test(){//select tel, count(*) as cnt from user group by tel order by cnt;QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();userQueryWrapper.select("tel","count(*) as cnt");userQueryWrapper.groupBy("tel");userQueryWrapper.orderByAsc("cnt");List<Map<String, Object>> mapList = userDao.selectMaps(userQueryWrapper); //selectMaps:根据 Wrapper 条件,查询全部记录System.out.println(JSON.toJSONString(mapList));}
3.6 字段映射与表名映射
| 注解 | 说明 |
|---|---|
| @TableField | 通过value属性(value="数据库中实际字段名"),设置当前属性对应的数据库表中的字段关系 |
| @TableField | 通过exist属性(true存在;false不存在),设置属性在数据库表字段中是否存在,默认为true。不能与value合并使用 |
| @TableField | 通过select属性(true参与;false不参与):设置该属性是否参与查询。此属性与select()映射配置不冲突。 |
| @TableName | 通过value属性@TableName("数据库中实际表名"),设置当前类对应的数据库表名称 |
4 DML编程控制
4.1 id生成策略控制(Insert)
| 注解 | 说明 |
|---|---|
| @TableId | 1、AUTO(0): 使用数据库id自增策略控制id生成;2、NONE(1):不设置id生成策略;3、INPUT(2):用户手工输入id;4、ASSIGN_ID(3):雪花算法生成id (可兼容数值型与字符串型);5、ASSIGN UUID(4):以UUID生成算法作为id生成策略 |
4.1.1 全局配置
mybatis-plus:global-config:db-config:id-type: assign_idtable-prefix: tbl_
4.2 逻辑删除(Delete/Update)
4.2.1 数据库表中添加逻辑删除字段

4.2.2 实体类中添加对应字段,并设定当前字段为逻辑删除标记字段
package com.itheima.domain;import com.baomidou.mybatisplus.annotation.*;import lombok.Data;@Data
public class User {private Long id;//逻辑删除字段,标记当前记录是否被删除@TableLogicprivate Integer deleted;}
4.2.2.1 全局配置逻辑删除字面值(不建议)
mybatis-plus:global-config:db-config:table-prefix: tbl_# 逻辑删除字段名logic-delete-field: deleted# 逻辑删除字面值:未删除为0logic-not-delete-value: 0# 逻辑删除字面值:删除为1logic-delete-value: 1
5 乐观锁(Update)
乐观锁的解决思想:
首先,在多个线程访问共享资源(数据库)时,给数据库添加一个version(int)的标记字段,然后,当某一个线程首先获取到数据库中资源是,version发生改变(常规操作自动加一),
相关文章:
MyBatisPlus Study Notes
文章目录1 MyBatisPlus概述1.1 MyBatis介绍1.2 MyBatisPlus特性2 标准数据层开发2.1 MyBatisPlus的CRUD操作API2.2 分页功能接口实现2.2.1 config(配置层)拦截器实现2.2.2 Dao(Mapper)数据访问层(CRUD)操作2.2.3 Junit单元测试进行…...
【Vu3 测试篇】自动化测试
一、为什么需要测试 自动化测试能够预防无意引入的 bug,并鼓励开发者将应用分解为可测试、可维护的函数、模块、类和组件。这能够帮助你和你的团队更快速、自信地构建复杂的 Vue 应用。与任何应用一样,新的 Vue 应用可能会以多种方式崩溃,因…...
Android system实战 — Android R(11) 第三方apk权限
Android system实战 — 第三方apk权限问题0. 前言1. 源码实现1.1 主要函数1.2 修改思路和实现1.2.1 修改思路1.2.2 方案一1.2.3 方案二0. 前言 最近在调试时遇到了第三方apk申请运行时权限,以及signature级别 install 权限不允许赋予给第三方apk,虽然这是…...
面试总结1
这里写目录标题什么是ORM?为什么mybatis是半自动的ORM框架?动态sqlJDBC步骤:jdbc的缺点:JDBC,MyBatis的区别:MyBatis相比JDBC的优势缓存一级缓存一级缓存在下面情况会被清除二级缓存最近在面试,发现了许多自…...
【Hello Linux】程序地址空间
作者:小萌新 专栏:Linux 作者简介:大二学生 希望能和大家一起进步! 本篇博客简介:简单介绍下进程地址空间 程序地址空间程序地址空间语言中的程序地址空间矛盾系统中的程序地址空间为什么要有进程地址空间思维导图总结…...
电脑崩溃蓝屏问题如何重装系统
电脑是我们日常生活和工作中必不可少的工具,但在使用过程中,难免会遇到各种问题,例如系统崩溃、蓝屏、病毒感染等,这些问题会严重影响我们的使用体验和工作效率。而小白一键重装系统可以帮助我们快速解决这些问题,本文…...
《商用密码应用与安全性评估》第一章密码基础知识1.2密码评估基本原理
商用密码应用安全性评估(简称“密评”)的定义:在采用商用密码技术、产品和服务集成建设的网络与信息系统中,对其密码应用的合规性、正确性、有效性等进行评估 信息安全管理过程 相关标准 国际:ISO/IEC TR 13335 中国:GB/T …...
【编程基础之Python】7、Python基本数据类型
【编程基础之Python】7、Python基本数据类型Python基本数据类型整数(int)基本的四则运算位运算比较运算运算优先级浮点数(float)布尔值(bool)字符串(str)Python数据类型变换隐式类型…...
Kakfa详解(一)
kafka使用场景 canal同步mysqlelk日志系统业务系统Topic kafka基础概念 Producer: 消息生产者,向kafka发送消息Consumer: 从kafka中拉取消息消费的客户端Consumer Group: 消费者组,消费者组是多个消费者的集合。消费者组之间互不影响,所有…...
图解LeetCode——剑指 Offer 12. 矩阵中的路径
一、题目 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相…...
particles在vue3中的基本使用
第三方库地址 particles.vue3 - npm 1.安装插件 npm i particles.vue3 npm i tsparticles2.在main.js中引入 import Particles from particles.vue3 app.use(Particles) // 配置相关的文件常用 api particles.number.value>粒子的数量particles.number.density粒子的稀密…...
04 Android基础--RelativeLayout
04 Android基础--RelativeLayout什么是RelativeLayout?RelativeLayout的常见用法:什么是RelativeLayout? 相对布局(RelativeLayout)是一种根据父容器和兄弟控件作为参照来确定控件位置的布局方式。 根据父容器定位 在相…...
python基础命令
1.现在包的安装路径 #pip show 包名 2.pip讲解 相信对于大多数熟悉Python的人来说,一定都听说并且使用过pip这个工具,但是对它的了解可能还不一定是非常的透彻,今天小编就来为大家介绍10个使用pip的小技巧,相信对大家以后管理和…...
用 Real-ESRGAN 拯救座机画质,自制高清版动漫资源
内容一览:Real-ESRGAN 是 ESRGAN 升级之作,主要有三点创新:提出高阶退化过程模拟实际图像退化,使用光谱归一化 U-Net 鉴别器增加鉴别器的能力,以及使用纯合成数据进行训练。 关键词:Real-ESRGAN 超分辨率 视…...
数据结构预备知识(模板)
模板 功能上类比C的重载函数,可以使用一种通用的形式,去代替诸多数据类型,使得使用同一种函数的时候,可以实现对于不同数据类型的相同操作。增强类和函数的可重用性。 使用模板函数为函数或类声明一个一般的模式,使得…...
SWM181按键控制双通道PWM固定占空比输出
SWM181按键控制双通道PWM固定占空比输出📌SDK固件包:https://www.synwit.cn/kuhanshu_amp_licheng/ 🌼开发板如下图: ✨注意新手谨慎选择作为入门单片机学习。目前只有一个简易的数据手册和SDK包,又没有参考手册&am…...
pygame函数命令
pygame.mixer.music.load() —— 载入一个音乐文件用于播放 pygame.mixer.music.play() —— 开始播放音乐流 pygame.mixer.music.rewind() —— 重新开始播放音乐 pygame.mixer.music.stop() —— 结束音乐播放 pygame.mixer.music.pause() —— 暂停音乐播放 pygame.mixer.mu…...
异步循环
业务 : 批量处理照片 , 批量拆建 , 裁剪一张照片需要异步执行等待 , 并且是批量 所以需要用到异步循环 裁剪图片异步代码 : 异步循环 循环可以是 普通 for 、 for of 、 for in 不能使用forEach ,这里推荐 for…...
Vue表单提交与数据存储
学习内容来源:视频p5 书接目录对页面重新命名选择组件后端对接测试接口设置接口前端调用对页面重新命名 将之前的 Page1 Page2 进行重新命名,使其具有实际意义 Page1 → BookManage ; Page2 → AddBook 并且 /router/index.js 中配置页面信息…...
API网关(接入层之上业务层之上)以及业务网关(后端服务网关)设计思路(二)
文章目录 流量网关业务网关常见网关对比1. OpenResty2. KongKong解决了什么问题Kong的优点以及性能Kong架构3. Zuul1.0过滤器IncomingEndpointOutgoing过滤器类型Zuul 1.0 请求生命周期4. Zuul2.0Zuul 与 Zuul 2 性能对比5. Spring Cloud GatewaySpring Cloud Gateway 底层使用…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...


