【SSM】MyBatisPlus笔记:快速上手MyBatisPlus
前言:
文章是系列学习笔记第11篇。基于黑马程序员课程完成,是笔者的学习笔记与心得总结,供自己和他人参考。笔记大部分是对黑马视频的归纳,少部分自己的理解,微量ai解释的内容(ai部分会标出)。
笔记1:【SSM】Spring学习笔记1: IoC的XML配置-CSDN博客 对应黑马课程P1~P20的内容。
笔记2:【SSM】Spring学习笔记2:注解配置bean-CSDN博客 对应黑马课程P21~P27
笔记3:【SSM】Spring学习笔记3:Spring整合MyBatis和Junit-CSDN博客 对应黑马课程P28~P30
笔记4:【SSM】Spring学习笔记4:Spring的AOP编程-CSDN博客 对应黑马课程P31~39
笔记5:【SSM】Spring学习笔记5:Spring事务-CSDN博客 对应黑马课程P40~42
笔记6: 【SSM】Spring学习笔记6:SpringMVC入门-CSDN博客 对应黑马课程P43~58
笔记7: 【SSM】SpringMVC学习笔记7:前后端数据传输协议和异常处理-CSDN博客 对应黑马课程P59~65
笔记8:【SSM】SpringMVC学习笔记8:拦截器-CSDN博客 对应黑马课程P71~74
笔记9:【SSM】SpringBoot学习笔记1:SpringBoot快速入门-CSDN博客 对应黑马课程P90~101
笔记10:【SSM】SpringBoot笔记2:整合Junit、MyBatis-CSDN博客 P102~103
笔记11:此篇 对应黑马课程P105~118
0. 是什么?
MyBatis框架的增强工具。简化MyBatis开发
官网mybatis-plus
1. 快速上手
官方提供的快速上手案例更为详细,建议阅读。
1.1 创建SpringBoot项目
选择起步依赖。注意无需选择MyBatis依赖
1.2 添加MyBatisPlus起步依赖
在项目的pom文件中手动添加MyBatisPlus起步依赖。这个依赖里面包含了MyBatis依赖,这就是上一步无需勾选MyBatis依赖的原因。如果上一步勾选了,可能还会导致版本冲突。
添加durid数据源依赖。
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency>
1.3 设置jdbc参数
根据自身情况在配置文件application.yml设置如下参数
1.4 准备好表结构和对应的实体类
tip:
实体类应该提供getter、setter方法
下面这个依赖提供了一些注解,如@Data
用在实体类上面自动提供getter、setter、toString、equals、hashCode等方法。
1.5 定义数据接口
接口继承BaseMapper,后面泛型是对应实体类。
该接口上添加注解@Mapper,MyBatis将会自动提供该接口对应的代理。
1.6 使用接口
2. 增删改查
使用一个实体类对象作为参数进行增删改查。
在“改”操作的时候,如果某个属性为空,数据库中对应字段不会修改,也不会变成null。
@SpringBootTest
class Mybatisplus01QuickstartApplicationTests {@Autowiredprivate UserDao userDao;//增@Testvoid testSave(){User user = new User();user.setName("黑马程序员");user.setPassword("itheima");user.setAge(12);user.setTel("4006184000");userDao.insert(user);}
//删@Testvoid testDelete(){userDao.deleteById(1401856123725713409L);}
//改@Testvoid testUpdate(){User user = new User();user.setId(1L);user.setName("Tom888");user.setPassword("tom888");userDao.updateById(user);}
//查@Testvoid testGetById(){User user = userDao.selectById(2L);System.out.println(user);}//查@Testvoid testGetAll() {List<User> userList = userDao.selectList(null);System.out.println(userList);}
}
分页查询
1 分页拦截器
开启这个功能MyBatisPlus提供的分页功能才能使用。将分页拦截器配置成bean。
【豆包】
@Configuration
注解的主要作用是:
- 声明配置类:被标注的类会被 Spring 容器识别为配置类,用于定义 Bean。
- 支持 Bean 方法:通过在配置类中定义
@Bean
注解的方法,声明 Spring 管理的对象。- 支持组件扫描:可结合
@ComponentScan
注解自动扫描并注册组件。- 支持 Java-based 配置:替代传统的 XML 配置文件,使配置更简洁、类型安全。
@Configuration
public class MpConfig {@Beanpublic MybatisPlusInterceptor mpInterceptor(){//1.定义Mp拦截器MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();//2.添加具体的拦截器mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());return mpInterceptor;}
}
2. 分页查询
分页查询对应方法selectPage接受的参数是IPage对象
@SpringBootTest
class Mybatisplus01QuickstartApplicationTests {@Autowiredprivate UserDao userDao;@Testvoid testGetByPage(){//IPage对象封装了分页操作相关的数据IPage page = new Page(2,3); //查询第二页,每页有3条数据userDao.selectPage(page,null);System.out.println("当前页码值:"+page.getCurrent());System.out.println("每页显示数:"+page.getSize());System.out.println("一共多少页:"+page.getPages());System.out.println("一共多少条数据:"+page.getTotal());System.out.println("数据:"+page.getRecords());}}
3. 条件查询
QueryWrapper
mybatisPlus提供了一个查询条件构建器 QueryWrapper。用它来设置查询的条件。
@Test
void testGetAll() {//方式一:按条件查询QueryWrapper qw = new QueryWrapper();qw.lt("age",18); //小于18岁List<User> userList = userDao.selectList(qw);//方式二:lambda格式按条件查询QueryWrapper<User> qw2 = new QueryWrapper<User>();qw2.lambda().lt(User::getAge, 10);List<User> userList2 = userDao.selectList(qw2);//方式三:lambda格式按条件查询LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();lqw.lt(User::getAge, 10);List<User> userList3 = userDao.selectList(lqw);
}
以上条件查询的时候,如果某个属性的值为null,可能会导致查询失败。因此可以设置当该属性不为null的时候才添加查询条件
投影查询
个人感觉第一种查询某些列的好用。但是复杂一点的查询语句还是使用mybatis。
其他条件查询
mybatis-plus的条件构造器 其他条件查询官网介绍更加细致。
4. 字段映射和表名映射
@Data
//设置表名映射关系
@TableName("tbl_user")
public class User {private Long id;private String name;
//该字段不参与查询@TableField(value = "pwd",select = false) private String password;private Integer age;private String tel;
//该字段数据库表中不存在@TableField(exist = false)private Integer online;}
5. id生成策略
myBatisPlus提供自动生成id的功能。使用该功能前提是数据库关闭自动生成id的功能。
通过设置注解@TableId的type属性,能够指定id生成策略。
如下面使用使用 MyBatis-Plus 内置的 雪花算法(Snowflake) 自动生成全局唯一 ID。
@Data
public class User {//设置主键生成策略@TableId(type = IdType.ASSIGN_ID)private Long id;//...
}
【豆包】
策略 说明 ASSIGN_ID
默认策略,使用雪花算法生成全局唯一长整型 ID(推荐分布式系统)。 AUTO
数据库自增(依赖数据库特性,如 MySQL 的 AUTO_INCREMENT
)。INPUT
手动输入 ID(插入数据前需自行设置主键值)。 ASSIGN_UUID
生成 32 位 UUID(字符串类型,不含 -
,如a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
)。NONE
未指定策略,此时需手动设置主键或依赖数据库自增。 ID_WORKER
旧版雪花算法(已弃用,推荐使用 ASSIGN_ID
)。ID_WORKER_STR
字符串类型的雪花算法 ID。
全局设置
配置文件application.yml加上如下内容,将默认使全局所有id的策略使用雪花算法策略。
mybatis-plus:global-config:banner: falsedb-config:id-type: assign_id
6. 多条数据一次查询/删除
@Test
void testDelete(){//删除指定多条数据List<Long> list = new ArrayList<>();list.add(1402551342481838081L);list.add(1402553134049501186L);list.add(1402553619611430913L);userDao.deleteBatchIds(list);//查询指定多条数据List<Long> list = new ArrayList<>();list.add(1L);list.add(3L);list.add(4L);userDao.selectBatchIds(list);
}
7. 逻辑删除
逻辑删除指的不真正的某些数据从数据库中删除,而是通过一个字段标记这行数据不可用来达到逻辑上删除该数据的效果。
数据库表设置逻辑删除字段
如下,使用deleted作为标记为逻辑删除的字段。并约定值为0为启用,值为1为逻辑禁用。
实体类中配置逻辑删除属性
@TableLogic字段标记该属性在数据库中表示逻辑删除的字段。
属性value设置未删除状态的值;delval设置已删除状态的值。
@Data public class User {private Long id;//...//逻辑删除字段,标记当前记录是否被删除@TableLogic(value = "0" ,delval = "1")private Integer deleted; }
全局设置逻辑删除字段
如果数据库中所有表都有表示逻辑删除的字段,且该字段名相同,约定表示启用和删除的值也相同,可以使用以下全局配置。
application.yml
mybatis-plus:global-config:db-config:# 逻辑删除字段名logic-delete-field: deleted# 逻辑删除字面值:未删除为0logic-not-delete-value: 0# 逻辑删除字面值:删除为1logic-delete-value: 1
8. 乐观锁
是什么?【豆包】
在并发场景下,当多个线程同时操作同一资源时,可能会出现数据竞争问题。乐观锁(Optimistic Locking)是一种用于解决并发冲突的机制,它假设系统中竞争条件(即多个线程同时修改同一数据)的概率较低,因此不需要像悲观锁(如数据库行锁、Java 的
synchronized
)那样在操作前提前锁定资源,而是在更新数据时检查是否有其他线程对数据进行了修改。如果有修改,则放弃本次操作或重试,从而避免数据不一致。核心思想:
- 假设乐观:默认认为数据在被读取时不会被其他线程修改。
- 版本控制:通过为数据添加一个 ** 版本号(Version)或时间戳(Timestamp)** 字段,在更新时验证版本是否一致,确保更新的是最新数据。
- 冲突检测:在提交更新前,检查数据的当前状态是否与读取时一致。若不一致,则认为发生了并发修改,拒绝本次更新。
mybatisPlus实现乐观锁
设置版本控制字段
首先保证数据库表中有一个表示版本控制号的字段。如下表使用version来表示版本控制
实体类中设置版本控制字段
使用@Version来标记版本控制字段
@Data public class User {@TableId(type = IdType.ASSIGN_ID) //...@Versionprivate Integer version; }
设置乐观锁拦截器
该拦截器会动态自动将修改操作的sql语句添加修改条件
@Configuration public class MpConfig {@Beanpublic MybatisPlusInterceptor mpInterceptor() {//1.定义Mp拦截器MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();//...添加其他拦截器// 添加乐观锁拦截器mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mpInterceptor;} }
使用乐观锁进行修改数据
9. 代码生成器
所有数据库表对应的实体类基本上都是一个套路写出来的。所有表包括id、逻辑删除字段(或者没有)、版本控制字段(或者没有)……
myBatisPlus提供了自动生成这些实体类代码的功能,只需要一些配置,如提供数据库信息,就能自动读取数据库表信息并生成对应的实体类。
使用方法
以下内容不需要记,大概知道即可。需要用到的时候再学。
1 导包
<!--代码生成器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version></dependency><!--velocity模板引擎--><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version></dependency>
2 创建生成器对象
3 数据源指定
4 其他配置
包相关的配置
策略相关的配置
public class CodeGenerator {public static void main(String[] args) {//1.获取代码生成器的对象AutoGenerator autoGenerator = new AutoGenerator();//设置数据库相关配置DataSourceConfig dataSource = new DataSourceConfig();dataSource.setDriverName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");dataSource.setUsername("root");dataSource.setPassword("root");autoGenerator.setDataSource(dataSource);//设置全局配置GlobalConfig globalConfig = new GlobalConfig();globalConfig.setOutputDir(System.getProperty("user.dir")+"/mybatisplus_04_generator/src/main/java"); //设置代码生成位置globalConfig.setOpen(false); //设置生成完毕后是否打开生成代码所在的目录globalConfig.setAuthor("黑马程序员"); //设置作者globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称globalConfig.setIdType(IdType.ASSIGN_ID); //设置Id生成策略autoGenerator.setGlobalConfig(globalConfig);//设置包名相关配置PackageConfig packageInfo = new PackageConfig();packageInfo.setParent("com.aaa"); //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径packageInfo.setEntity("domain"); //设置实体类包名packageInfo.setMapper("dao"); //设置数据层包名autoGenerator.setPackageInfo(packageInfo);//策略设置StrategyConfig strategyConfig = new StrategyConfig();strategyConfig.setInclude("tbl_user"); //设置当前参与生成的表名,参数为可变参数strategyConfig.setTablePrefix("tbl_"); //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名 例如: User = tbl_user - tbl_strategyConfig.setRestControllerStyle(true); //设置是否启用Rest风格strategyConfig.setVersionFieldName("version"); //设置乐观锁字段名strategyConfig.setLogicDeleteFieldName("deleted"); //设置逻辑删除字段名strategyConfig.setEntityLombokModel(true); //设置是否启用lombokautoGenerator.setStrategy(strategyConfig);//2.执行生成操作autoGenerator.execute();} }
调试的时候开启日志功能
在配置文件application.yml添加以下内容,即可看到数据库查询时候输出的日志。
# 开启mp的日志(输出到控制台)
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl