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 底层使用…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...