SpringBoot整合Mybatis-Plus
文章目录
- 前言
- 一、Mybatis-Plus简介
- 二、框架结构
- 三、SpringBoot整合Mybatis-Plus
- 1.依赖
- 2.配置文件设置
- 四、前期准备
- 4.1数据库信息
- 4.2dao类
- 4.3pojo类
- 五、常用注解
- 5.1 @TableName(value = "")
- 5.2 @TableId(value="",type = IdType.XXX)
- 5.3 @TableField("")
- 5.4@TableLogic(value = "0",delval = "1")
- 六、方法演示
- 6.1 新增
- 6.2 根据ID修改
- 6.3 根据名字修改
- 6.4 根据ID查询
- 6.4 根据ID批量查询
- 6.5 查询count
- 6.6 查询List
- 6.7 lambda表达式按照条件动态查询
- 6.8 查询字段
- 6.9 聚合查询
- 6.10 分组查询
- 6.11 分页查询
- 6.12 逻辑删除
- 总结
前言
本文章将演示SpringBoot整合Mybatis-Plus以及常用常用注解方法
一、Mybatis-Plus简介
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window) 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
二、框架结构

通过结构图可以看出MyBatisPlus专门提供了mybatis-plus-boot-starter供SpringBoot使用
三、SpringBoot整合Mybatis-Plus
1.依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version>
</dependency>
注:此依赖整合了Mybatis和Mybatis-Plus,所以尽量不要再加mybatis的依赖,以免冲突
2.配置文件设置
mybatis:configuration://默认是不允许自动转换驼峰命名,得自己设置为truemap-underscore-to-camel-case: true//起别名type-aliases-package: com.apesource.pojo
mybatis-plus:configuration://默认是允许自动转换驼峰命名map-underscore-to-camel-case: true//开启日志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
注:mybatis和mybatis-plusd 配置是相互独立且生效的
四、前期准备
4.1数据库信息

4.2dao类
@Mapper
public interface StudentMapper extends BaseMapper<Student> {
}
dao层的接口使用@Mapper声明可以被自动注入,并且继承Mybatis-Plus提供的BaseMapper类实现通过mapper对象调用CDUR方法
4.3pojo类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Serializable {private int stuId;private String stuName;private String stuNick;private String stuHobby;private int stuAge;private int deleted;public Student(String stuName, String stuNick, String stuHobby, int stuAge) {this.stuName = stuName;this.stuNick = stuNick;this.stuHobby = stuHobby;this.stuAge = stuAge;}public Student(String stuName, String stuNick, String stuHobby) {this.stuName = stuName;this.stuNick = stuNick;this.stuHobby = stuHobby;}
}
五、常用注解
5.1 @TableName(value = “”)
作用:将类对应到数据库的某个表上
位置:类
参数:value=表的字段名
5.2 @TableId(value=“”,type = IdType.XXX)
作用:将数据库的主键字段映射到类的属性中
位置:成员变量
参数:value=表的字段名;type=AUTO(0),NONE(1),INPUT(2),ASSIGN_ID(3),ASSIGN_UUID(4);
5.3 @TableField(“”)
作用:将类的属性映射到表的字段
位置:成员变量
参数:value=表的字段名
5.4@TableLogic(value = “0”,delval = “1”)
作用:开启逻辑删除,0表示未删除,1表示以及删除
位置:成员变量
参数:value=正常状态的值,delval=被删除后的值
注:此注解声明的成员变量只有MybatisPlus能识别,如果使用mybatis的方法查询的话,还是能查询到状态是已删除的信息
将以上注解用与Studen类中
@TableName(value = "student")
public class Student implements Serializable {
@TableId(value="stu_id",type = IdType.AUTO)private int stuId;@TableField("stu_name")private String stuName;@TableField("stu_nick")private String stuNick;@TableField("stu_hobby")private String stuHobby;@TableField("stu_age")private int stuAge;@TableField(value = "deleted")@TableLogic(value = "0",delval = "1")private int deleted;
}public Student(String stuName, String stuNick, String stuHobby, int stuAge) {this.stuName = stuName;this.stuNick = stuNick;this.stuHobby = stuHobby;this.stuAge = stuAge;}public Student(String stuName, String stuNick, String stuHobby) {this.stuName = stuName;this.stuNick = stuNick;this.stuHobby = stuHobby;}
六、方法演示
6.1 新增
在测试类中注入
@Autowired
StudentMapper mapper;
@Testpublic void test01() {Student student = new Student("李逵", "黑旋风", "飞斧", 33);int i = mapper.insert(student);System.out.println(i);}
结果如图:

6.2 根据ID修改
//修改ID@Testpublic void test02() throws Exception {Student student = new Student();student.setStuId(7);student.setStuName("鲁智深");student.setStuAge(38);int i = mapper.updateById(student);System.out.println(i);}
结果如图:

6.3 根据名字修改
@Testpublic void test03() throws Exception {//1.修改数据Student student = new Student();student.setStuHobby("拔杨柳");//2.创建条件QueryWrapper wrapper = new QueryWrapper();wrapper.eq("stu_name", "鲁智深");int update = mapper.update(student, wrapper);System.out.println(update);}
结果如图:

6.4 根据ID查询
//根据ID查询@Testpublic void test04() throws Exception {Student student = mapper.selectById(3);System.out.println(student);}
结果如图:

6.4 根据ID批量查询
//根据ID批量查询@Testpublic void test05() throws Exception {List<Student> students = mapper.selectBatchIds(Arrays.asList(1, 3, 5, 6));students.forEach(System.out::println);}
结果如图:

6.5 查询count
//查询count@Testpublic void test06() throws Exception {QueryWrapper<Student> wrapper = new QueryWrapper<>();wrapper.eq("stu_hobby", "csgo");Integer integer = mapper.selectCount(wrapper);System.out.println(integer);}
结果如图:

6.6 查询List
//查询list@Testpublic void test07() throws Exception {QueryWrapper<Student> wrapper = new QueryWrapper<>();
// wrapper.eq("stu_hobby","csgo").or().eq("stu_age",21);wrapper.eq("stu_hobby", "csgo");wrapper.eq("stu_age", 21);//根据wrapper里的条件查询,返回一个集合List<Student> students = mapper.selectList(wrapper);students.forEach(student -> System.out.println(student));}
结果如图:

6.7 lambda表达式按照条件动态查询
//模拟动态查询@Testpublic void test09() {//1.前端发送来的数据Integer num1 = null;Integer num2 = 30;//1.查询条件LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();//2.判断
// if(null != num2){
// wrapper.lt(Student::getStuAge,num2);
// }
// if(null != num1){
// wrapper.gt(Student::getStuAge,num1);
// }wrapper.gt(num1 != null, Student::getStuAge, num1);wrapper.lt(num2 != null, Student::getStuAge, num2);//3.查询List<Student> students = mapper.selectList(wrapper);students.forEach(System.out::println);}
结果如图:

6.8 查询字段
@Testpublic void test10() {//1.条件LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();wrapper.select(Student::getStuName, Student::getStuHobby);//2.查询List<Student> students = mapper.selectList(wrapper);//4.遍历students.forEach(System.out::println);}
结果如图:

6.9 聚合查询
//投影查询-聚合查询@Testpublic void test11() {//1.查询条件QueryWrapper<Student> wrapper = new QueryWrapper<Student>();//2.判断wrapper.select("count(*) as total,max(stu_age) as maxage,sum(stu_age) as sumage");//3.查询List<Map<String, Object>> list = mapper.selectMaps(wrapper);//4.遍历list.forEach(Map::entrySet);}
结果如图:

6.10 分组查询
//分组查询@Testpublic void test12() {//1.查询条件QueryWrapper<Student> wrapper = new QueryWrapper<Student>();//2.判断wrapper.select("count(*) as num1,stu_hobby");wrapper.groupBy("stu_hobby");//3.查询List<Map<String, Object>> list = mapper.selectMaps(wrapper);//4.遍历list.forEach(System.out::println);}
结果如图:

6.11 分页查询
使用分页查询需要在配置类中注入分页类
@Configuration
public class SpringBootConfig {//注入mp拦截器@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){//1.实例化拦截器MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//2.分页拦截器mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
// mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}
}
/*** mp分页使用* 注意:* 1.page.setCurrent(2);当前页码从1开始* 2.分页需要配置插件* 3.mp坐标版本3.1.1不能使用过高版本*/@Testpublic void test13() throws Exception {//1.定义分页规则IPage<Student> page = new Page<Student>();page.setSize(2);//每页记录数page.setCurrent(2);//当前页码//2.查询条件(可选)IPage<Student> iPage = mapper.selectPage(page, null);List<Student> records = iPage.getRecords();//分页结果records.forEach(System.out::println);System.out.println("每页容量" + iPage.getSize());System.out.println("总记录数:" + iPage.getTotal());System.out.println("总记页数:" + iPage.getPages());}
结果如图:

6.12 逻辑删除
/*** 物理删除:业务数据从数据库中丢弃,执行的是delete操作* 逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,* 数据保留在数据库中,执行的是update操作* 实现步骤:* 步骤1:修改数据库表添加`deleted`列,比如`0`代表正常,`1`代表删除,可以在添加列的同时设置其默认值为`0`正常。* 步骤2:实体类添加属性以及注解** @TableLogic(value="0",delval="1") private Integer deleted;* value为正常数据的值,delval为删除数据的值*///逻辑删除@Testpublic void test14() {mapper.deleteById(6);}
结果如图:


逻辑删除不会真正的将数据从数据库删除,而是对此时使用修改的方式对 @TableLogic声明的属性修改值;但是使用mybatis-plus的查询方法无法将它查到;
总结
由上可知SpringBoot整合Mybatis-Plus后对数据库操作有多方便,因为Mybatis-Plus有强大的条件构造器,满足各类使用需求内置的Mapper,通用的Service,少量配置即可实现单表大部分CRUD操作,支持Lambda形式调用提供了基本的CRUD功能,连SQL语句都不需要编写,自动解析实体关系映射转换为MyBatis内部对象注入容器
相关文章:
SpringBoot整合Mybatis-Plus
文章目录 前言一、Mybatis-Plus简介二、框架结构三、SpringBoot整合Mybatis-Plus1.依赖2.配置文件设置 四、前期准备4.1数据库信息4.2dao类4.3pojo类 五、常用注解5.1 TableName(value "")5.2 TableId(value"",type IdType.XXX)5.3 TableField("&qu…...
在langchain中使用自定义example selector
在langchain中使用自定义example selector 简介 在之前的文章中,我们提到了可以在跟大模型交互的时候,给大模型提供一些具体的例子内容,方便大模型从这些内容中获取想要的答案。这种方便的机制在langchain中叫做FewShotPromptTemplate。 如…...
pytest常用执行参数详解
1. 查看pytest所有可用参数 我们可以通过pytest -h来查看所有可用参数。 从图中可以看出,pytest的参数有很多,下面是归纳一些常用的参数: -s:输出调试信息,包括print打印的信息。 -v:显示更详细的信息。 …...
本地项目如何连接git远程仓库
在本地新建项目后,如何连接git远程仓库呢?步骤如下: 第一步, 首先我们在git上新建仓库,设置模板可勾选Readme文件。(readme文件的创建是为了介绍所写代码的一些详细信息,为了之后更好的维护。)…...
力扣 494. 目标和
题目来源:https://leetcode.cn/problems/target-sum/description/ C题解(来源代码随想录):将该问题转为01背包问题。 假设加法的总和为x,那么减法对应的总和就是sum - x。所以我们要求的是 x - (sum - x) target。x …...
Maven-搭建私有仓库
使用NEXUS REPOSITORY MANAGER 3在Windows上搭建私有仓库。 NEXUS REPOSITORY MANAGER 3 是一个仓库管理系统。 下载NEXUS3 官网上是无法下载的,所以网上搜nexus-3.18.1-01-win64就能搜到,下载即可。 安装NEXUS3 下载nexus-3.18.0-01-win64.zip至相应目录下(路径不要有中文)。 …...
PostgreSql 参数配置
一、访问控制参数配置 https://xiaosonggong.blog.csdn.net/article/details/124264877 二、数据库参数配置 2.1 概述 PostgreSQL 的参数配置参数是在 postgresql.conf 文件中集中管理的,类似于 Oracle 的 pfile 文件,除此之外,PostgreSQL…...
【BMC】OpenBMC开发基础2:修改原有程序
修改原有程序 通常情况下我们会需要修改OpenBMC原有的程序来适配我们的项目,本节将介绍一般的流程。 为此首先我们需要了解devtool这个工具,注意它不是前端开发用的那个devtool,而是由OE(或者Yocto?)提供…...
2012年数学建模竞赛脑卒中发病环境因素分析及干预日期数据处理代码
因四个表格日期数据处理有些复杂,故作此代码一次性处理四组数据: import datetime import pandas as pddef check(string, df, i, num, error_list):if is_valid(pd.to_datetime(string, errorscoerce, format%Y/%m/%d), error_list, i):df.iloc[i, nu…...
Merge和Rebase的区别
Merge 和 Rebase 是 Git 中常用的两种分支整合方式,它们具有不同的工作原理和效果: Merge(合并) 合并是将两个或多个分支的提交历史合并为一个新的提交。在合并时,Git 会创建一个新的合并提交,将两个分支…...
[RTKLIB]模糊度固定相关问题(二)
文章目录 一、固定模糊度的前置工作1. 做好固定模糊度的准备2. 建立双差模糊度3. 问题与总结 版权声明:本文为原创文章,版权归 Winston Qu 所有,转载请注明出处。 在上一篇文章中,介绍了RTKLIB中manage_amb_LAMBDA()函数ÿ…...
QtAV for ubuntu16.04
下载ubuntu https://releases.ubuntu.com/16.04/ubuntu-16.04.7-desktop-amd64.iso 下载ffmpeg https://ffmpeg.org/download.html 下载QtAV https://github.com/wang-bin/QtAV/releases 更新 sudo apt update 安装库 sudo apt-get install libglu1-mesa-dev freeglut3-dev…...
MFC 文件读写包括字符串的结构体
试过CString char* 写入的都是地址 struct Param{int ID;int index;char val[128]; };vector<Param>ans; UINT count 17; ans.resize(count); FILE* fp; fopen_s(&fp,_T("my.txt"),_T("rb")); if(count ! fread(&ans[0],sizeof(Param),cou…...
在家构建您的迷你聊天Chat gpt
推荐:使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 什么是指令遵循模型? 语言模型是机器学习模型,可以根据句子的前一个单词预测单词概率。如果我们向模型请求下一个单词,并将其递减地反馈给模型以请求更多单词ÿ…...
pytest自动化测试框架之断言
前言 断言是完整的测试用例中不可或缺的因素,用例只有加入断言,将实际结果与预期结果进行比对,才能判断它的通过与否。 unittest 框架提供了其特有的断言方式,如:assertEqual、assertTrue、assertIn等,py…...
C++模板的用法
目录 模板的概念 函数模板(Function Templates) 基本用法 函数模板的实例化 匹配原则 类模板(Class Templates) 模板的概念 C中的模板(Templates)实际上是一种泛型编程(Generic Programm…...
ESP 32 蓝牙虚拟键盘链接笔记本电脑的键值问题
由于打算利用esp32 通过蓝牙链接电脑后实现一些特俗的键盘功能,所以就折腾了一下,折腾最耗费时间的却是键值问题,让一个20多年的老司机重新补充了知识 过程曲折就不说了,直接说结果。 我们通过网络搜索获取的键值和蓝牙模拟键盘传…...
128.【Maven】
Maven仓库 (一)、Maven 简介1.传统项目管理的缺点2.Maven是什么3.Maven的作用 (二)、Maven 的下载与安装1.下载与认识目录2.配置Maven的全局环境 (三)、Maven 的基础概念1.Maven 仓库(1).仓库分类 2. Maven 坐标3.Maven 本地仓库配置(1).改变默认的仓库地址(2).改变远程仓库地址…...
嵌入式虚拟仿真实验教学平台之串口发送数据
嵌入式虚拟仿真实验教学平台课程系列 串口发送数据实验 课程内容 本实验使用 STM32 的串口发送数据。开始仿真后,打开串口监视器,串口监视器会打印出要发送的数据。 课程目标 学习配置使用GPIO功能学习配置使用复用功能学习配置使用UART功能 硬件设计 本课程…...
Android Studio 屏幕适配
Android开发屏幕适配流程 首先studio中没有ScreenMatch这个插件的,下去现在这个插件 点击File->settings->Plugins->(搜索ScreenMatch插件),点击下载,应用重启Studio即可,如下图 在values下 创建dimens.xml,…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
