概述
![](https://file2.kaopuke.com:8081/files_image/2023060822/af17da4234b37492271ce423ddabb57b.png)
学习目标
能够基于MyBatisPlus完成标准Dao开发
能够掌握MyBatisPlus的条件查询
能够掌握MyBatisPlus的字段映射与表名映射
能够掌握id生成策略控制
能够理解代码生成器的相关配置
一、MyBatisPlus简介
MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率
开发方式
基于MyBatis使用MyBatisPlus
基于Spring使用MyBatisPlus
基于SpringBoot使用MyBatisPlus
1. 入门案例
![](https://file2.kaopuke.com:8081/files_image/2023060822/630089e5624e9e4a9c491110e26d00d4.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/b1930b000e3952b5751d8f6801f96c5e.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/0771ae8adf521d74922afa363607a57b.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/94314060ac3c83d305f21cfe9f67c663.png)
①:创建新模块,选择Spring初始化,并配置模块相关基础信息
![](https://file2.kaopuke.com:8081/files_image/2023060822/ef0ba038da597a5d6d09f97466ee6d38.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/893ca0206ab1f1cc756b38007ca72cc6.png)
②:选择当前模块需要使用的技术集(仅保留JDBC)
![](https://file2.kaopuke.com:8081/files_image/2023060822/1388f7899b9497b5069c3619362b8b2c.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/604589abf5ed86cdcd829915137827bd.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/fe030f910d5f6077012689eb8ccdfe87.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/5395318ad11d4de20fd9b0fd4931d7b1.png)
③:手动添加MyBatisPlus起步依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--添加mybatisplus的依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
注意事项1:由于mp并未被收录到idea的系统内置配置,无法直接选择加入
注意事项2:如果使用Druid数据源,需要导入对应坐标
④:制作实体类与表结构
(类名与表名对应,属性名与字段名对应)
新建一个数据库mybatisplyus
![](https://file2.kaopuke.com:8081/files_image/2023060822/1c2df60f474103ead68670ab970180cd.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/d6eaea409642be362eaf71897cff0609.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/2c4d2d763392eb25157e7efeb2ec20d4.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/b7416b0743d294ce826d696e5d2a1cec.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/528199ff3bdbfb8fb2c3ea198dea62b2.png)
⑤:设置Jdbc参数(application.yml)
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=UTC
username: root
password: 123456
⑥:定义数据接口,继承BaseMapper
![](https://file2.kaopuke.com:8081/files_image/2023060822/b92586298590e9372cd6b8381c0f0473.png)
//使用mp,dao的写法,只需要继承一个父亲接口就可以BaseMapper,还要注意加上泛型
@Mapper
public interface UserDao extends BaseMapper<User> {
}
⑦:测试类中注入dao接口,测试功能
查询所有
@SpringBootTest
public class TestUserDao {
@Autowired
private UserDao userDao;
//查询所有
@Test
void testFindAll() {
List<User> list = userDao.selectList(null);
System.out.println("list=" +list);
}}
![](https://file2.kaopuke.com:8081/files_image/2023060822/92a23fde6265279b35fcf4afdcc064e6.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/5390efef5bd18b23ec202305a77648b2.png)
2. MyBatisPlus概述
问题导入
通过入门案例制作,MyBatisPlus的优点有哪些?
2.1 MyBatis介绍
MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率
官网:https://mybatis.plus/ https://mp.baomidou.com/
2.2 MyBatisPlus特性
无侵入:只做增强不做改变,不会对现有工程产生影响
强大的 CRUD 操作:内置通用 Mapper,少量配置即可实现单表CRUD 操作
支持 Lambda:编写查询条件无需担心字段写错
支持主键自动生成
内置分页插件
……
二、标准数据层开发
1. MyBatisPlus的CRUD操作
![](https://file2.kaopuke.com:8081/files_image/2023060822/85b9561e63cdbd4f74ecdc9bbacb810b.png)
下面用MP进行CURD
1.1添加
// 新增
@Test
void testAdd() {
User user = new User();
user.setName("黑马程序员");
user.setPassword("itheima");
user.setAge(12);
user.setTel("4006184000");
int row = userDao.insert(user);
System.out.println("row = " + row);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/ed79516a374ac3b007e5f0f144823625.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/ae2531913c10e2f4a7d871462da8a6eb.png)
1.2 删除
这里面因为刚才不小心多增加一个相同内容 所以这里面删除的话id就用雪花
//删除
@Test
void testDelete() {
// int row = userDao.deleteById(3);
int row = userDao.deleteById(1631599267871215618L);
System.out.println("row = " + row);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/4fa515d6a1b819353ffb465a6485fe99.png)
我们现在把另一个也删除了
![](https://file2.kaopuke.com:8081/files_image/2023060822/d068f0f5f7970d1026894ebf5c5e5be4.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/8273cff8405a26989257cbae84fd354f.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/f289e7e1fd3ec3daf00b56e444840a52.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/727f8db3384f9856d7202146fe0502d5.png)
1.3 修改
//修改
@Test
void testUpdate() {
//1.先查询数据
User user = userDao.selectById(2);
user.setPassword("777");
//2.修改
int row = userDao.updateById(user);
System.out.println("row = " + row);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/a8ddbb3590ea0b84320aa0dca31c159c.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/6c822a2b260ed5b02bdf2548ed78f999.png)
1.4 查询单个
//查询单个
@Test
void testFindById() {
User user = userDao.selectById(2);
System.out.println("user = " + user);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/fb567d9bedde93d31289426582d99ad3.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/686c2524c75ee1f6b4350a0eaf78dcde.png)
2. Lombok插件介绍
问题导入
有什么简单的办法可以自动生成实体类的GET、SET方法?
Lombok,一个Java类库,提供了一组注解,简化POJO实体类开发。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
常用注解:==@Data==,为当前实体类在编译期设置对应的get/set方法,无参/无参构造方法,toString方法,hashCode方法,equals方法等
package com.itheima.domain;
import lombok.*;
/*
1 生成getter和setter方法:@Getter、@Setter
生成toString方法:@ToString
生成equals和hashcode方法:@EqualsAndHashCode
2 统一成以上所有:@Data
3 生成空参构造: @NoArgsConstructor
生成全参构造: @AllArgsConstructor
4 lombok还给我们提供了builder的方式创建对象,好处就是可以链式编程。 @Builder【扩展】
*/
@Data
public class User {
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
}
3. MyBatisPlus分页功能
问题导入
思考一下Mybatis分页插件是如何用的?
3.1 分页功能接口
![](https://file2.kaopuke.com:8081/files_image/2023060822/1d5ef8fe8a120f9cb0a928de7f0c8ce8.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/81ce4147436df41a8e53025208d2502e.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/50e8187f762ae63343e5245b63d12c80.png)
3.2 MyBatisPlus分页使用
![](https://file2.kaopuke.com:8081/files_image/2023060822/61dfdb01631f895a2f157d9e02dd6836.png)
①:执行分页查询
Ipage 接口
用MP后 是有一个selectPage() 方法 然后这个方法传进去一个对象page 这里面就已经包装了查第几页 每页查第多少条
![](https://file2.kaopuke.com:8081/files_image/2023060822/01b6638d26a1dd00078d8a6a5cffd37e.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/d34265d727acedbc2e336f70ed975716.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/aa3737c004652bb510315252df1e6412.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/047f666bde291014c8e40c833261bf08.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/235f8602b06235d11869caaee2dbb58d.png)
//分面查询
@Test
void testFindPage() {
/** @param current 当前页
* @param size 每页显示条数*/
//1 创建IPage分页对象,设置分页参数 当前页为第一页 每页显示条数为2条
//IPage<User> page =new Page<>(1,2);
//1 创建IPage分页对象,设置分页参数 当前页为第二页 每页显示条数为2条
IPage<User> page =new Page<>(2,2);
//2 执行分页查询
IPage<User> iPage = userDao.selectPage(page, null);
//3 获取分页结果
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());
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/92a3234843b5212aee54bc0f173ccbdf.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/484fcfd21a125804054748b3e4e683db.png)
②:设置分页拦截器作为Spring管理的bean
@Configuration
public class MybatisPlusConfig {
/*配置分页拦截器,需要打上@Bean的注解,暴露给spring使用*/
@Bean
public MybatisPlusInterceptor mpi(){
//1 创建MybatisPlus拦截器对象
MybatisPlusInterceptor mpi =new MybatisPlusInterceptor();
//2 添加分页拦截器
mpi.addInnerInterceptor(new PaginationInnerInterceptor());
//返回MyBatisplus的拦截器对象
return mpi;
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/31ace8c8aabbea03a6c71d09f9324c82.png)
重新运行发现 这回正常了
![](https://file2.kaopuke.com:8081/files_image/2023060822/9d183547f4061b507f844226fc0d9324.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/0b83f59388d4ea46164042894f887cb3.png)
3.3 开启MyBatisPlus日志
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=UTC
username: root
password: 123456
# 开启mp的日志(输出到控制台)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
![](https://file2.kaopuke.com:8081/files_image/2023060822/34e59abe727a7419db5d05ce234d521a.png)
3.4 解决日志打印过多问题
3.4.1 取消初始化spring日志打印
![](https://file2.kaopuke.com:8081/files_image/2023060822/3a9a33664f1b1ba16e5512157956a808.png)
做法:在resources下新建一个logback.xml文件,名称固定,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
</configuration>
关于logback参考播客:https://www.jianshu.com/p/75f9d11ae011
3.4.2 取消SpringBoot启动banner图标
![](https://file2.kaopuke.com:8081/files_image/2023060822/87539eef5fd4e750dadd6b3b304f34fb.png)
spring:
main:
banner-mode: off # 关闭SpringBoot启动图标(banner)
3.4.3 取消MybatisPlus启动banner图标
![](https://file2.kaopuke.com:8081/files_image/2023060822/72cc52e7839ee159a1b104ce52c95f59.png)
# mybatis-plus日志控制台输出
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
banner: off # 关闭mybatisplus启动图标
三、DQL编程控制
环境准备
![](https://file2.kaopuke.com:8081/files_image/2023060822/c163b29c3393400522ddf1355cf0c7b7.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/fcbaf8ddec8c20412475b2731e3cc427.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/fcd911dabc1e3b4f773ea7a93f16505b.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/84bc4cf52a3b9ab48fd320b920451c04.png)
依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--添加mybatisplus的依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
从demo1复制依赖 yml dao bean
测试类test.TestUserDao
![](https://file2.kaopuke.com:8081/files_image/2023060822/22bea8ca73b8d57dd97568a8ec2176d1.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/e2aeccd7b46171ec971b649b29100978.png)
1. 条件查询方式
MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完成查询条件的组合
![](https://file2.kaopuke.com:8081/files_image/2023060822/326ec9e11eb20f62da3aaf2c077a8a1b.png)
1.1 条件查询
无条件全查
@SpringBootTest
public class TestUserDao {
@Autowired
private UserDao userDao;
@Test
public void findByCondition(){
//查询年龄大于等于18岁 小于65岁的用户
//1.构建条件对象
QueryWrapper<User> qw =new QueryWrapper<>();
//1.1 添加条件
//2.执行查询
List<User> list = userDao.selectList(qw);
System.out.println("list = " + list);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/85b7df4b3ad07b15640b3426571a9046.png)
1.1.1 方式一:按条件查询
@SpringBootTest
public class TestUserDao {
@Autowired
private UserDao userDao;
@Test
public void findByCondition(){
//查询年龄大于等于18岁 小于65岁的用户
//1.构建条件对象
QueryWrapper<User> qw =new QueryWrapper<>();
//1.1 添加条件
qw.ge("age",18);
qw.lt("age",65);
//2.执行查询
List<User> list = userDao.selectList(qw);
System.out.println("list = " + list);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/3019fa0d86d651d32839b1e3473f4386.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/7c5e2ac6171115a613d9c5080d89ad26.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/2adefab092fe4138b42ac2bb0afdc7fb.png)
链式写法
`@SpringBootTest
public class TestUserDao {
@Autowired
private UserDao userDao;
@Test
public void findByCondition(){
//查询年龄大于等于18岁 小于65岁的用户
//1.构建条件对象
QueryWrapper<User> qw =new QueryWrapper<>();
//1.1 添加条件
//常规
// qw.ge("age",18);
// qw.lt("age",65);
//链式写法
qw.ge("age",18).lt("age",65);
//2.执行查询
List<User> list = userDao.selectList(qw);
System.out.println("list = " + list);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/a026963a74bfe4af4a81a71e860e6cd4.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/af4b65ac9b913be105afb43a017cf3a2.png)
1.1.2 方式二:lambda格式按条件查询
//使用条件查询[使得lambda格式按条件查询]
@Test
public void findByCondition02(){
//查询年龄大于等于18岁 小于65岁的用户
//1.构建条件对象
QueryWrapper<User> qw =new QueryWrapper<>();
//1.1 添加条件
//常规
qw.lambda().ge(User::getAge,18).lt(User::getAge,65);
//2.执行查询
List<User> list = userDao.selectList(qw);
System.out.println("list = " + list);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/0182abcbc43275fc6e4c863f521ae50d.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/452dbda4848bb5e871eb0ba5f4742196.png)
1.1.3 方式三:lambda格式按条件查询(推荐)
//使用条件查询[使得lambda格式按条件查询(推荐)]
@Test
public void findByCondition03(){
//查询年龄大于等于18岁 小于65岁的用户
//1.构建条件对象
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//1.1 添加条件
//使用方法引用定位列的名字,可以很好的防止手动写列名,引发的一些问题。
//常规
lqw.ge(User::getAge,18);
lqw.lt(User::getAge,65);
//2.执行查询
List<User> list = userDao.selectList(lqw);
System.out.println("list = " + list);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/a7651a8312c728446287d679559f6dca.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/955844551a3e563c32621e85dcb4fef4.png)
1.2 组合条件
1.2.1 并且关系(and)
@Test
public void findByCondition04(){
//查询年龄大于等于18岁 小于65岁的用户
//1.构建条件对象
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//1.1 添加条件
//使用方法引用定位列的名字,可以很好的防止手动写列名,引发的一些问题。
//常规
lqw.ge(User::getAge,18).lt(User::getAge,65);
//2.执行查询
List<User> list = userDao.selectList(lqw);
System.out.println("list = " + list);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/6df753efc25640a1ab679fbb75a05aad.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/38fb3a754c0abb1328500bda6d59443c.png)
1.2.2 或者关系(or)
//查询年龄小于等于18岁 或者年龄大于65岁的用户
//如果使用或者,那么需要使用or() 来连接多个条件
@Test
public void findByCondition05(){
//1.构建条件对象
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//2.添加条件
lqw.le(User::getAge,18).or().gt(User::getAge,65);
//2.执行查询
List<User> list = userDao.selectList(lqw);
System.out.println("list = " + list);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/25796e228ab548712bcba59e19ccdfda.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/01b514dfeba4e5775e9a2f1221b0b2d5.png)
1.3 NULL值处理
问题导入
如下搜索场景,在多条件查询中,有条件的值为空应该怎么解决?
![](https://file2.kaopuke.com:8081/files_image/2023060822/f84c165cc9c14495439a7207477ad65a.png)
1.3.1 if语句控制条件追加
原始写法
` //============空值的处理(其实就是以前的动态sql)==========
@Test
public void findByCondition06(){
//1. 组装数据【理论上,这份数据应该是从浏览器的页面传递过来】
//1.1 浏览器传递过来的数据 有多有少 可有可无
//1.2 如果传递过来了所有的这三个条件数据 那么表示想按照条件来查询
//1.3 传递多少个数据,就有多少个条件被追加
User u = new User();
u.setName("admin");
u.setPassword("123456");
u.setTel("10086");
//2.组装条件
LambdaQueryWrapper<User> qw = new LambdaQueryWrapper<>();
//2。1 原始的写法
//a.判断数据身上是否有用户名 有 就追加条件
if (u.getName() != null) {
qw.eq(User::getName,u.getName());
}
//b.判断数据身上是否有密码 ,有,就追加条件
if (u.getPassword() !=null) {
qw.eq(User::getPassword,u.getPassword());
}
//c.判断数据身上是否有电话,有,就追加条件
if (u.getTel() !=null) {
qw.eq(User::getTel,u.getTel());
}
//3.执行查询
List<User> list = userDao.selectList(qw);
System.out.println("list = " + list);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/bdcbec20438f0671a697a8c661e7cf47.png)
1.3.2 条件参数控制
//平时在处理页面上进行搜索过滤的代码
@Test
public void findByCondition07(){
//1. 组装数据【理论上,这份数据应该是从浏览器的页面传递过来】
//1.1 浏览器传递过来的数据 有多有少 可有可无
//1.2 如果传递过来了所有的这三个条件数据 那么表示想按照条件来查询
//1.3 传递多少个数据,就有多少个条件被追加
User u = new User();
u.setName("admin");
u.setPassword("123456");
u.setTel("10086");
//2.组装条件
LambdaQueryWrapper<User> qw = new LambdaQueryWrapper<>();
//a.判断数据身上是否有用户名 有 就追加条件
//参数一;就是用来标记这个条件要不要添加进去,如果是true,即表示要添加条件
qw.eq(u.getName() !=null, User::getName,u.getName());
//b.判断数据身上是否有密码 ,有,就追加条件
qw.eq(u.getPassword() != null,User::getPassword,u.getPassword());
//c.判断数据身上是否有电话,有,就追加条件
qw.eq(u.getTel() !=null,User::getTel,u.getTel());
//3.执行查询
List<User> list = userDao.selectList(qw);
System.out.println("list = " + list);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/f9b53d561fcf6b09b980af82ccf9af97.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/b70a5f379c30b7c84e51d5258d3e5559.png)
2. 查询投影-设置【查询字段、分组、分页】
2.1 查询结果包含模型类中部分属性
//===============投影查询 和统计查询==================
//投影查询:指的就是查询少量的列。不是面对所有的列
@Test
public void findByCondition08(){
//======第一种写法=====
//1.使用QueryWrap
QueryWrapper<User> qw = new QueryWrapper<>();
//1.1 设置查询的具体列
qw.select("id","name","password");
//2.执行查询
List<User> userList = userDao.selectList(qw);
System.out.println("userList = " + userList);
System.out.println("---------------------------------------");
//=================第二种写法==============
//2.使用 LambdaQueryWrapper来做
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//2.1 设置查询哪些类
lqw.select(User::getId ,User::getName,User::getPassword);
//3.执行查询
List<User> list = userDao.selectList(lqw);
System.out.println("list = " + list);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/6c39137730867a82a1228ab9e2f2bcf9.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/2675ced54bda663cb272b440ce5eb5fe.png)
2.2 查询结果包含模型类中未定义的属性
补:因为我这里面分组用到的是男女分组 而我们数据库里面没有性别这个字段 所以我们在先加一下这个字段
![](https://file2.kaopuke.com:8081/files_image/2023060822/0c8cc410f21501aef92b9d676111f6ba.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/8fbc96921ef9e808f091b7b019c4d7aa.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/208516518c0ec5ab190673aa0fd6bda6.png)
@Test
public void findByCondition09(){
//统计查询:统计性别的数量
// 1.定义条件对象
QueryWrapper<User> qw = new QueryWrapper<User>();
//2.追加条件
//qw.select("gender,count(*) as number");
//一个列就是一个参数数字字符串
qw.select("gender","count(*) as number");
//分组
qw.groupBy("gender");
//3.执行查询
//执行查询返回的是List集合里面装Map集合
//每一条记录就是一个Map集合,map集合的KEY就是列的名字,map集合的value就是列的值。
List<Map<String, Object>> mapList = userDao.selectMaps(qw);
System.out.println("mapList = " + mapList);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/65527d1c12dd1945d272166c4edbd910.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/fd6b3cadafb13e7d6cfefdcf063e82a2.png)
3. 查询条件设定
问题导入
多条件查询有哪些组合?
范围匹配(> 、 = 、between)
模糊匹配(like)
空判定(null)
包含性匹配(in)
分组(group)
排序(order)
……
模糊匹配(like)
//模糊查询
@Test
public void testFindByCondition10(){
//1. 创建条件对象
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//2. 追加条件
lqw.like(User::getName , "i");
//3. 执行查询
List<User> list = userDao.selectList(lqw);
System.out.println("list = " + list);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/b6b6abafc3c82f5eb8a87c5fbf8a3582.png)
3.1 查询条件
用户登录(eq匹配)
//查询单条记录,使用selectOne() :: 登录的场景
@Test
public void testFindByCondition11(){
//1. 创建条件对象
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//2. 追加条件
lqw.eq(User::getName , "zhangsan");
lqw.eq(User::getPassword , "777");
//3. 执行查询
User user = userDao.selectOne(lqw);
System.out.println("user = " + user);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/5a8bf59c7fe64bfce3ad9bad709f82c3.png)
购物设定价格区间、户籍设定年龄区间(le ge匹配 或 between匹配)
//区间查询: 使用 between 来实现 , 查询年龄大于等于18 ,并且小于等于65岁
@Test
public void testFindByCondition12(){
//1. 创建条件对象
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//2. 追加条件
//lqw.ge(User::getAge , 18).le(User::getAge , 65);
//前后都包含
lqw.between(User::getAge , 18 , 65);
//3. 执行查询
List<User> userList = userDao.selectList(lqw);
System.out.println("userList = " + userList);
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/ad6449f93f5f85fe09a837ad4a1b98ac.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/93681180d392aab93a910ab0d9fd3f37.png)
3.2 查询API
更多查询条件设置参看 https://mybatis.plus/guide/wrapper.html#abstractwrapper
4. 字段映射与表名映射
问题导入
思考表的字段和实体类的属性不对应,查询会怎么样?
4.1 问题一:表字段与编码属性设计不同步
在模型类属性上方,使用@TableField属性注解,通过==value==属性,设置当前属性对应的数据库表中的字段关系。
![](https://file2.kaopuke.com:8081/files_image/2023060822/ec78a3230cdec1073236d5f9018760ed.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/3d3136c678538fc6fc72f76f49af21d8.png)
环境准备
![](https://file2.kaopuke.com:8081/files_image/2023060822/0077e246d6684c9ac356f5d3b0e08fcc.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/8e95e635b8648e1fa3b0463e0906bc92.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/e186e8b50b30ece84bdb0fd93bd5767a.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/06e20f048c55ab322fa40da78e743847.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/39e7ccc51ddfd66a636c37eba0dfce49.png)
建立表
CREATE TABLE `user02` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号' ,
`name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名' ,
`pwd` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码' ,
`age` int(3) NOT NULL COMMENT '年龄' ,
`tel` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '电话' ,
PRIMARY KEY (`id`)
)
![](https://file2.kaopuke.com:8081/files_image/2023060822/e88fcdcdf371f26f7019848cc1c6a6fa.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/418a23cf1250ae6eb59d1a306c55adfe.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/22af53e94cd20d7a7a6b7e13c25db2d9.png)
依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--添加mybatisplus的依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
![](https://file2.kaopuke.com:8081/files_image/2023060822/51160cfe73f1cc02943b17b760aef505.png)
复制 bean yml
创建dao
@Mapper
public interface UserDao extends BaseMapper<User02> {
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/068d8b137a1dcf7a8d3a88527775f278.png)
创建测试类
@SpringBootTest
public class TestUserDao {
@Autowired
private UserDao userDao;
@Test
public void testFindAll(){
//查询所有
List<User02> list = userDao.selectList(null);
System.out.println("list = " + list);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/3dc737065cb290f1bb8c3a9a8a999dbc.png)
跑起来发现报错
### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'password' in 'field list'
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Unknown column 'password' in 'field list'
![](https://file2.kaopuke.com:8081/files_image/2023060822/05e7efa0f37d18710d7b0138e3024d95.png)
错误原因解释
/*
1. mybatisplus 执行查询的时候,它并不是直接使用 select * 来做的查询
2. 它是通过解读dao 身上的 泛型,找到具体的类
public interface UserDao extends BaseMapper<User02>
3. 所以后续的UserDao的操作,它都是根据User02类来指导。
3.1 把类名的名字变成小写,那么就是表的名字。【默认】
3.2 查询表的所有的数据不是采用 * 来执行,怎么知道user02 有哪些列呢?
它是这么认为的,一般类当中的属性名一定和表里面的列名一样。!
3.3 写: select 列1, 列2, 列3 ... from user02 等价于
select 属性1, 属性2, 属性3, .... from user02.
4. 如果属性名和列的名字对不上,那么查询就报错了!
4.1 在不一样的属性名上面加上一个注解 @TableField, 可以认为给属性起一个别名。
*/
解决办法:
在不一样的属性名上面加上一个注解 @TableField, 可以认为给属性起一个别名
@Data
public class User02 {
private Long id;
private String name;
/*
1. mybatisplus 执行查询的时候,它并不是直接使用 select * 来做的查询
2. 它是通过解读dao 身上的 泛型,找到具体的类
public interface UserDao extends BaseMapper<User02>
3. 所以后续的UserDao的操作,它都是根据User02类来指导。
3.1 把类名的名字变成小写,那么就是表的名字。【默认】
3.2 查询表的所有的数据不是采用 * 来执行,怎么知道user02 有哪些列呢?
它是这么认为的,一般类当中的属性名一定和表里面的列名一样。!
3.3 写: select 列1, 列2, 列3 ... from user02 等价于
select 属性1, 属性2, 属性3, .... from user02.
4. 如果属性名和列的名字对不上,那么查询就报错了!
4.1 在不一样的属性名上面加上一个注解 @TableField, 可以认为给属性起一个别名。
*/
@TableField("pwd")
private String password;
private Integer age;
private String tel;
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/cb069223af30d55c6c323daa9da22315.png)
补:
这个不是报错 idea发现你要注入时并没有任何对象被管理起来 如果不想让有这条线 就在UserDao里面添加@Repository注解就可以了 当然这个不会影响我们的使用 所以我们可以不用去管他
![](https://file2.kaopuke.com:8081/files_image/2023060822/397497d6ffa8bad0aa39141688daeeba.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/555a5a048743401ecf1308c3ffcee939.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/3fd78959151503594facc36f9029af3c.png)
4.2 问题二:编码中添加了数据库中未定义的属性
在模型类属性上方,使用@TableField注解,通过==exist==属性,设置属性在数据库表字段中是否存在,默认为true。此属性无法与value合并使用。
![](https://file2.kaopuke.com:8081/files_image/2023060822/ba934260d2ab88c009c29fc798865559.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/09d6392b84e1273a254c1b6964c15c18.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/dc71f8592fc6da1afba161e50bd238c6.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/7526e3f078b87a1c2bdc2540f629fa04.png)
问题分析:
/*
1. 当类里面出现了一个属性,这个属性并没有在表里面有任何一个列与之对应
2. 要告诉mybatisplus 这个属性并不是要和表里面哪个列进行对应,
2.1 通俗一点就是告诉MP。 这个属性不是表里面列,查询的时候不要带上它。
2.2 只需要在属性上加上注解@TableField ,设置里面的exist属性的值为 false
2.3 那么在执行表的查询工作的时候,就不会带上这个属性了。
3. 既然表里面没有这个列,那么为什么类当中要有这样的属性存在呢? 什么场景下会有这种情况出现!
3.1 JavaBean 是用来封装数据的,这份数据姑且认为,就是从数据库得到的数据。
3.2 封装好数据之后,要返回给前端【浏览器】,在浏览器上展示数据。
3.3 有一种极端的情况:
3.3.1 从数据库里面得到的数据,在页面上并不足以支撑它的数据展示。
3.3.2 比如:以前品牌的,状态值。
数据库里面存储的是 1 和 0
页面要展示的是: 启用 和 禁用。
3.3.3 可以在类当中追加一个属性: private String statusStr; 用来处理字符串状态值的。
*/
![](https://file2.kaopuke.com:8081/files_image/2023060822/1cd631b81f77b8df2c8e4944ac266583.png)
报错情况如下
### SQL: SELECT id,name,pwd AS password,age,tel,online FROM user02
### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'online' in 'field list'
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Unknown column 'online' in 'field list'
![](https://file2.kaopuke.com:8081/files_image/2023060822/1562393fe7528d9f2701bf0aeaea510c.png)
解决办法:
package com.itheima.bean;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
@Data
public class User02 {
private Long id;
private String name;
/*
1. mybatisplus 执行查询的时候,它并不是直接使用 select * 来做的查询
2. 它是通过解读dao 身上的 泛型,找到具体的类
public interface UserDao extends BaseMapper<User02>
3. 所以后续的UserDao的操作,它都是根据User02类来指导。
3.1 把类名的名字变成小写,那么就是表的名字。【默认】
3.2 查询表的所有的数据不是采用 * 来执行,怎么知道user02 有哪些列呢?
它是这么认为的,一般类当中的属性名一定和表里面的列名一样。!
3.3 写: select 列1, 列2, 列3 ... from user02 等价于
select 属性1, 属性2, 属性3, .... from user02.
4. 如果属性名和列的名字对不上,那么查询就报错了!
4.1 在不一样的属性名上面加上一个注解 @TableField, 可以认为给属性起一个别名。
*/
@TableField("pwd")
private String password;
private Integer age;
private String tel;
/*
1. 当类里面出现了一个属性,这个属性并没有在表里面有任何一个列与之对应
2. 要告诉mybatisplus 这个属性并不是要和表里面哪个列进行对应,
2.1 通俗一点就是告诉MP。 这个属性不是表里面列,查询的时候不要带上它。
2.2 只需要在属性上加上注解@TableField ,设置里面的exist属性的值为 false
2.3 那么在执行表的查询工作的时候,就不会带上这个属性了。
3. 既然表里面没有这个列,那么为什么类当中要有这样的属性存在呢? 什么场景下会有这种情况出现!
3.1 JavaBean 是用来封装数据的,这份数据姑且认为,就是从数据库得到的数据。
3.2 封装好数据之后,要返回给前端【浏览器】,在浏览器上展示数据。
3.3 有一种极端的情况:
3.3.1 从数据库里面得到的数据,在页面上并不足以支撑它的数据展示。
3.3.2 比如:以前品牌的,状态值。
数据库里面存储的是 1 和 0
页面要展示的是: 启用 和 禁用。
3.3.3 可以在类当中追加一个属性: private String statusStr; 用来处理字符串状态值的。
*/
@TableField(exist = false)
private String online;
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/639639159d3373e53c85ed9edc770f9e.png)
问题解决之后控制台显示:
![](https://file2.kaopuke.com:8081/files_image/2023060822/38bc562c1b3ca964226fc8bb6a328924.png)
4.3 问题三:采用默认查询开放了更多的字段查看权限
在模型类属性上方,使用@TableField注解,通过==select==属性:设置该属性是否参与查询。此属性与select()映射配置不冲突。
![](https://file2.kaopuke.com:8081/files_image/2023060822/5b1412f7ad5bdf3a6b65912513e70328.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/33c546da70678348529253cca40dffeb.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/9354e1d6ad0ff89ff9d93714bffb3ac5.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/ab8477e90e68c5ec8e1c9319bb7ddc5c.png)
问题分析:设置不让查询后 我们就查询不到 在生活场景中比较经常用到的是不查密码 不要密码查询出来
/*
1. 如果在执行查询操作的时候,不希望把这个类的数据给查询出来,那么可以加上@TableField注解
2. 通过设置里面的select属性的值为 false, 那么它将不参与查询!
3. 如果从结果来看的话,select和exist并没有什么区别,结果一样:
3.1 exist讲究的是这个属性【列】在表里面有还是没有
3.2 select讲究的是这个属性【列】到底要不要查询出来,这个列在表里一定是有的。
3.3 在写入操作上也有区别:
select标记的属性,在执行增删改的时候还是会参与的,但是 exist 标记的属性就不会参与,因为没有这个列
*/
解决办法:
package com.itheima.bean;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
@Data
public class User02 {
private Long id;
private String name;
/*
1. mybatisplus 执行查询的时候,它并不是直接使用 select * 来做的查询
2. 它是通过解读dao 身上的 泛型,找到具体的类
public interface UserDao extends BaseMapper<User02>
3. 所以后续的UserDao的操作,它都是根据User02类来指导。
3.1 把类名的名字变成小写,那么就是表的名字。【默认】
3.2 查询表的所有的数据不是采用 * 来执行,怎么知道user02 有哪些列呢?
它是这么认为的,一般类当中的属性名一定和表里面的列名一样。!
3.3 写: select 列1, 列2, 列3 ... from user02 等价于
select 属性1, 属性2, 属性3, .... from user02.
4. 如果属性名和列的名字对不上,那么查询就报错了!
4.1 在不一样的属性名上面加上一个注解 @TableField, 可以认为给属性起一个别名。
*/
@TableField("pwd")
private String password;
/*
1. 如果在执行查询操作的时候,不希望把这个类的数据给查询出来,那么可以加上@TableField注解
2. 通过设置里面的select属性的值为 false, 那么它将不参与查询!
3. 如果从结果来看的话,select和exist并没有什么区别,结果一样:
3.1 exist讲究的是这个属性【列】在表里面有还是没有
3.2 select讲究的是这个属性【列】到底要不要查询出来,这个列在表里一定是有的。
3.3 在写入操作上也有区别:
select标记的属性,在执行增删改的时候还是会参与的,但是 exist 标记的属性就不会参与,因为没有这个列
*/
@TableField(select = false)
private Integer age;
private String tel;
/*
1. 当类里面出现了一个属性,这个属性并没有在表里面有任何一个列与之对应
2. 要告诉mybatisplus 这个属性并不是要和表里面哪个列进行对应,
2.1 通俗一点就是告诉MP。 这个属性不是表里面列,查询的时候不要带上它。
2.2 只需要在属性上加上注解@TableField ,设置里面的exist属性的值为 false
2.3 那么在执行表的查询工作的时候,就不会带上这个属性了。
3. 既然表里面没有这个列,那么为什么类当中要有这样的属性存在呢? 什么场景下会有这种情况出现!
3.1 JavaBean 是用来封装数据的,这份数据姑且认为,就是从数据库得到的数据。
3.2 封装好数据之后,要返回给前端【浏览器】,在浏览器上展示数据。
3.3 有一种极端的情况:
3.3.1 从数据库里面得到的数据,在页面上并不足以支撑它的数据展示。
3.3.2 比如:以前品牌的,状态值。
数据库里面存储的是 1 和 0
页面要展示的是: 启用 和 禁用。
3.3.3 可以在类当中追加一个属性: private String statusStr; 用来处理字符串状态值的。
*/
@TableField(exist = false)
private String online;
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/ceb33c89158bd6ae144e4463496eca1b.png)
解决完成问题之后 的控制台显示
![](https://file2.kaopuke.com:8081/files_image/2023060822/64e583b52c8465d5312b2a72487404ee.png)
4.4 问题四:表名与编码开发设计不同步
在模型类上方,使用@TableName注解,通过==value==属性,设置当前类对应的数据库表名称。
![](https://file2.kaopuke.com:8081/files_image/2023060822/e1b22e34e6282ab35e6c104126cb7684.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/3add745fb1e227eb8dcb72985d10239b.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/b8dfa1d391fc0d6dc687758a32620b40.png)
为了演示 我们把表名修改成t_user
![](https://file2.kaopuke.com:8081/files_image/2023060822/9c5ea0bf651ad8b25536b3e70c7cc7ab.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/2fae55e8e9d9c5b5b03d4f45d69e93ef.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/d9c2484d7af74c1fe38f952e2dd2b26c.png)
我们把数据库中的表名修改之后 回来看Dao 发现还是写的是user02 因为他都是按照javabean来写的
![](https://file2.kaopuke.com:8081/files_image/2023060822/95a5dd388368a96532cb452e54b71841.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/07a13dd29880ef4d848c046cedba2a26.png)
发现我们数据库表中并没有类名小写后的名字 所以这个时候如何启动 就会报错
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Table 'mybatisplus.user02' doesn't exist
![](https://file2.kaopuke.com:8081/files_image/2023060822/422db889b899eb4214366df84782b107.png)
解决办法
package com.itheima.bean;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/*
1. 当类名和表的名字不一致的时候,那么执行操作就会失败。
2. 因为MP, 操作的时候,默认就会把类的名字变成小写,然后充当表名去操作。
3. 可以在类上打注解:
@TableName("具体的表名")
*/
@Data
@TableName("t_user")
public class User02 {
private Long id;
private String name;
/*
1. mybatisplus 执行查询的时候,它并不是直接使用 select * 来做的查询
2. 它是通过解读dao 身上的 泛型,找到具体的类
public interface UserDao extends BaseMapper<User02>
3. 所以后续的UserDao的操作,它都是根据User02类来指导。
3.1 把类名的名字变成小写,那么就是表的名字。【默认】
3.2 查询表的所有的数据不是采用 * 来执行,怎么知道user02 有哪些列呢?
它是这么认为的,一般类当中的属性名一定和表里面的列名一样。!
3.3 写: select 列1, 列2, 列3 ... from user02 等价于
select 属性1, 属性2, 属性3, .... from user02.
4. 如果属性名和列的名字对不上,那么查询就报错了!
4.1 在不一样的属性名上面加上一个注解 @TableField, 可以认为给属性起一个别名。
*/
@TableField("pwd")
private String password;
/*
1. 如果在执行查询操作的时候,不希望把这个类的数据给查询出来,那么可以加上@TableField注解
2. 通过设置里面的select属性的值为 false, 那么它将不参与查询!
3. 如果从结果来看的话,select和exist并没有什么区别,结果一样:
3.1 exist讲究的是这个属性【列】在表里面有还是没有
3.2 select讲究的是这个属性【列】到底要不要查询出来,这个列在表里一定是有的。
3.3 在写入操作上也有区别:
select标记的属性,在执行增删改的时候还是会参与的,但是 exist 标记的属性就不会参与,因为没有这个列
*/
@TableField(select = false)
private Integer age;
private String tel;
/*
1. 当类里面出现了一个属性,这个属性并没有在表里面有任何一个列与之对应
2. 要告诉mybatisplus 这个属性并不是要和表里面哪个列进行对应,
2.1 通俗一点就是告诉MP。 这个属性不是表里面列,查询的时候不要带上它。
2.2 只需要在属性上加上注解@TableField ,设置里面的exist属性的值为 false
2.3 那么在执行表的查询工作的时候,就不会带上这个属性了。
3. 既然表里面没有这个列,那么为什么类当中要有这样的属性存在呢? 什么场景下会有这种情况出现!
3.1 JavaBean 是用来封装数据的,这份数据姑且认为,就是从数据库得到的数据。
3.2 封装好数据之后,要返回给前端【浏览器】,在浏览器上展示数据。
3.3 有一种极端的情况:
3.3.1 从数据库里面得到的数据,在页面上并不足以支撑它的数据展示。
3.3.2 比如:以前品牌的,状态值。
数据库里面存储的是 1 和 0
页面要展示的是: 启用 和 禁用。
3.3.3 可以在类当中追加一个属性: private String statusStr; 用来处理字符串状态值的。
*/
@TableField(exist = false)
private String online;
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/2db66d40974fa262b4f3ec635052529d.png)
映射之后执行结果
![](https://file2.kaopuke.com:8081/files_image/2023060822/bc37136c41790643faf6ec1f0a4d6360.png)
四、DML编程控制
环境准备
![](https://file2.kaopuke.com:8081/files_image/2023060822/ecf3369649f46177776d705ddc7281e2.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/dc0dce9ed52688d4786ee14c9251f1a9.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/25daa3282516e367dd2e83320313407c.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/2cd1d22f25f58e8938a4ad5ba5bafb7e.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/e8d01518323b02b4e0a9766c8e95714e.png)
依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--添加mybatisplus的依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
![](https://file2.kaopuke.com:8081/files_image/2023060822/9d4c9787eee43de5e1354bc915d4eeb7.png)
复制bean dao
追加一个属性
![](https://file2.kaopuke.com:8081/files_image/2023060822/ddaa7a896b1dfb014c6d046cd9723358.png)
环境准备完成
1. id生成策略控制(Insert)
问题导入
主键生成的策略有哪几种方式?
不同的表应用不同的id生成策略
日志:自增(1,2,3,4,……)
购物订单:特殊规则(FQ23948AK3843)
外卖单:关联地区日期等信息(10 04 20200314 34 91)
关系表:可省略id
……
1.1 id生成策略控制(@TableId注解)
名称:@TableId
类型:属性注解
位置:模型类中用于表示主键的属性定义上方
作用:设置当前类中主键属性的生成策略
相关属性
type:设置主键属性的生成策略,值参照IdType枚举值
![](https://file2.kaopuke.com:8081/files_image/2023060822/36128526865c404d81e4932436b800b4.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/bc4652fa5f394ef1565fbacded415a7b.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/3f2c1d184254c14459f4843ca809df9b.png)
添加测试类
package com.itheima.test;
import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class TestUserDao {
@Autowired
private UserDao userDao;
@Test
public void testAdd(){
User u = new User(null, "张三", "123", 18, "100", "男");
//userDao.insert(u);
//userDao.deleteById(1632424817103765505L);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/5dcdf28a8cdc6889977df47b7d2b1238.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/4e6bb5021c02e3c84c8bb3596302d283.png)
这里面要注意的是main启动类里面启动没有多环境配置并不影响测试类的输出 所以这里面如果看到没有激活springboot时 如下图所示 先不用去管他 这里面先不用去激活
![](https://file2.kaopuke.com:8081/files_image/2023060822/a4cbcf575652fa5ae444a43f0297555a.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/2aff69eb4909dc96789189e4181a29ff.png)
修改包装类的原因是因为有时我们的Id 如果不想给的话 我们可以直接给一个null
![](https://file2.kaopuke.com:8081/files_image/2023060822/dcfcc66775f2129b48870f004ed815d4.png)
@TableId(type = IdType.AUTO) AUTO: 表示使用数据库自增的id
![](https://file2.kaopuke.com:8081/files_image/2023060822/443838f2ebaa31fa1a750411b9e94cf4.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/cd615ea0b2ac0c344b1856a24b18d2eb.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/8c22d4aa0b44fc0d590879d03f81cee5.png)
@TableId(type = IdType.INPUT) INPUT: 以用户输入的为准,如果有输入的话。
![](https://file2.kaopuke.com:8081/files_image/2023060822/619fca325d096b5a94fd1f32d7ba3086.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/77664e2967fea23c2e61efc9ab0ce7bf.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/09d2e755a5d9e9f07e523012a0cc8ff5.png)
1.2 全局策略配置
mybatis-plus:
global-config:
db-config:
id-type: assign_id
table-prefix: tbl_
id生成策略全局配置
![](https://file2.kaopuke.com:8081/files_image/2023060822/6c7faeeee0032d279d392753fa1745eb.png)
表名前缀全局配置
![](https://file2.kaopuke.com:8081/files_image/2023060822/cdccc7afebbe9d6275a75bd24bd8c663.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/77e35704bc8adbc73b1fddbaa551e59e.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/bb59a7bab843731e4f067ba78afdc30a.png)
2. 多记录操作(批量Delete/Select)
问题导入
MyBatisPlus是否支持批量操作?
![](https://file2.kaopuke.com:8081/files_image/2023060822/cd736e29ddcc321a4d76e25b2ac038ff.png)
2.1 按照主键删记录
![](https://file2.kaopuke.com:8081/files_image/2023060822/12d41efe23ba453a998ad98f26f550d5.png)
package com.itheima.test;
import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
//演示多记录操作: 批量删除和批量查询
@SpringBootTest
public class TestUserDao02 {
@Autowired
private UserDao userDao;
@Test
public void testDeleteBatch(){
List<Long> ids = Arrays.asList(new Long[]{1632433992487747586L, 1632433992487747587L});
//批量删除
int row = userDao.deleteBatchIds(ids);
System.out.println("row = " + row);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/522b3aef95f0ebdab3fa1dbe73dd9cb9.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/ffbfed4fe66cbf82b6cf8abb54e1aa48.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/4c31fa6ec82d65a19421ec500fc34874.png)
这里面要注意一下 因为我们前面表名前缀全局配置设置了一个表tb_ 会影响到 所以把user里面tb_表先注释掉 不然会报错 说找不到这张表 报错如下
![](https://file2.kaopuke.com:8081/files_image/2023060822/c1abb76988297d25b7f3f56b6b69da2f.png)
解决办法
![](https://file2.kaopuke.com:8081/files_image/2023060822/04191c22611653f3dcbbc0a74d3bb194.png)
2.2 根据主键查询多条记录
//演示多记录操作: 批量删除和批量查询
@SpringBootTest
public class TestUserDao02 {
@Autowired
private UserDao userDao;
@Test
public void testQueryBatch(){
List<Long> ids = Arrays.asList(new Long[]{1L, 2L,3L,4L ,333L,1632431756852400130L});
//批量查询
List<User> list = userDao.selectBatchIds(ids);
System.out.println("list = " + list);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/e01706173edac31f78d5d478d76fa955.png)
3. 逻辑删除(Delete/Update)
![](https://file2.kaopuke.com:8081/files_image/2023060822/4952d60b3e271b810d48036c7d534734.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/25303b825386e7bc865ee7e1306dfa15.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/b5f5d60023edec2193fc77c634ea0cc3.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/feba54eb78cbbf715d4291e218ec76ae.png)
问题导入
在实际环境中,如果想删除一条数据,是否会真的从数据库中删除该条数据?
删除操作业务问题:业务数据从数据库中丢弃
逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中
![](https://file2.kaopuke.com:8081/files_image/2023060822/894f1f83855b86b0520dd0adf2fd384a.png)
3.1 逻辑删除案例
①:数据库表中添加逻辑删除标记字段
![](https://file2.kaopuke.com:8081/files_image/2023060822/0546a9d88e1802fab3e3404bbd3b2e08.png)
②:实体类中添加对应字段,并设定当前字段为逻辑删除标记字段
`package com.itheima.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.awt.*;
//@TableName("tb_user")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
/*
ID生成策略:
1. 默认情况下,mybatisplus 使用的是雪花算法的策略
2. id策略:
AUTO: 表示使用数据库自增的id
NONE: 没有设置,约等于INPUT
INPUT: 以用户输入的为准,如果有输入的话。
ASSIGN_ID : 雪花算法生成的id,默认使用的是这个。
ASSIGN_UUID : 使用uuid 来生成id
*/
@TableId(type = IdType.INPUT)
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
private String gender;
/*
这是一个逻辑删除字段
1. 首先先在表里面增加一个列,名字: deleted
2. 自己心里衡量删除的值和未删除的值,删除的字段的值是 1, 没有删除的时候,字段的值是 0.
3. 在JavaBean 里面定义已给属性: deleted
4. 打上注解,标记这个属性是一个逻辑删除属性。
4.1 配置属性 value : 未删除的值
4.2 配置属性 deval : 删除的值
5. 可以在代码里面配置,也可以在application.yml里面全局配置
*/
@TableLogic(delval = "1" , value = "0")
private int deleted;
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/9de3bbc78038f0f845a84b42463d1dce.png)
//演示逻辑删除
@SpringBootTest
public class TestUserDao03 {
@Autowired
private UserDao userDao;
@Test
public void testDelete(){
userDao.deleteById(1);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/d9dde7af77146544246858a72c8b3a02.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/f69af2d8c9279c1b5d4d143c22e9829a.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/2621677b393f01ebb8947ed7b7265235.png)
逻辑删除是做的更新操作 那么我们查询时会查询到逻辑删除后的数据吗?
答:不会的
例子:
package com.itheima.test;
import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.List;
//演示逻辑删除
@SpringBootTest
public class TestUserDao03 {
@Autowired
private UserDao userDao;
@Test
public void testFindAll(){
List<User> list = userDao.selectList(null);
System.out.println("list = " + list);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/a373040507d8c3c2962ebdb5fa34f0f5.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/9cd8ee82f360a7b84eefdb45c3ef4b31.png)
③:配置逻辑删除字面值
逻辑删除本质:逻辑删除的本质其实是修改操作。如果加了逻辑删除字段,查询数据时也会自动带上逻辑删除字段。
![](https://file2.kaopuke.com:8081/files_image/2023060822/e9fdc26abad41108ea565a4ae6fe4651.png)
`spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=UTC
username: root
password: 123456
# 配置输出sql语句
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# table-prefix: tb_ # 全局设置表名的前缀
id-type: auto # 设置主键策略,对全部的表都有影响
logic-delete-field: deleted # 设置删除的逻辑字段
logic-delete-value: 1 # 设置删除的值
logic-not-delete-value: 0 # 设置未删除的值
# mybatisplus的全局配置
![](https://file2.kaopuke.com:8081/files_image/2023060822/4a87656d0e646284afb9d6ee22fe943a.png)
4. 乐观锁(Update)
增加一个字段
![](https://file2.kaopuke.com:8081/files_image/2023060822/9231c8ff5b4eb2f7b2c8b115a5d77513.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/d03f7addca79436ee6603543457b0750.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/eef37d1a31d47eb160e8b2991330d005.png)
复制config配置类
问题导入
乐观锁主张的思想是什么?
业务并发现象带来的问题:秒杀
![](https://file2.kaopuke.com:8081/files_image/2023060822/a01d6f03b1facc96c2e4dd2e8ce80293.png)
4.1 乐观锁案例
①:数据库表中添加锁标记字段
![](https://file2.kaopuke.com:8081/files_image/2023060822/de7b1e54e133a69ba08dce7358ce5de9.png)
②:实体类中添加对应字段,并设定当前字段为逻辑删除标记字段
package com.itheima.bean;
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.awt.*;
//@TableName("tb_user")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
/*
ID生成策略:
1. 默认情况下,mybatisplus 使用的是雪花算法的策略
2. id策略:
AUTO: 表示使用数据库自增的id
NONE: 没有设置,约等于INPUT
INPUT: 以用户输入的为准,如果有输入的话。
ASSIGN_ID : 雪花算法生成的id,默认使用的是这个。
ASSIGN_UUID : 使用uuid 来生成id
*/
@TableId(type = IdType.INPUT)
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
private String gender;
/*
这是一个逻辑删除字段
1. 首先先在表里面增加一个列,名字: deleted
2. 自己心里衡量删除的值和未删除的值,删除的字段的值是 1, 没有删除的时候,字段的值是 0.
3. 在JavaBean 里面定义已给属性: deleted
4. 打上注解,标记这个属性是一个逻辑删除属性。
4.1 配置属性 value : 未删除的值
4.2 配置属性 deval : 删除的值
5. 可以在代码里面配置,也可以在application.yml里面全局配置
*/
//@TableLogic(delval = "1" , value = "0")
private int deleted;
// 表示这个属性是一个乐观锁的属性
@Version
private int version;
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/3ef9628202531c966fa334d2eeb81cfe.png)
③:配置乐观锁拦截器实现锁机制对应的动态SQL语句拼装
package com.itheima.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
/**
* 配置分页拦截器,需要打上@Bean的注解,暴露给spring使用
* @return
*/
@Bean
public MybatisPlusInterceptor mpi(){
//1. 创建MyBatisplus的拦截器对象
MybatisPlusInterceptor mpi = new MybatisPlusInterceptor();
//2. 往它身上添加分页拦截器
mpi.addInnerInterceptor(new PaginationInnerInterceptor());
//3. 追加乐观锁的拦截器
mpi.addInnerInterceptor(new OptimisticLockerInnerInterceptor() );
//4. 返回MyBatisplus的拦截器对象
return mpi;
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/f69f57d2538f399f36bf7334d4240348.png)
④:使用乐观锁机制在修改前必须先获取到对应数据的verion方可正常进行
package com.itheima.test;
import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
//演示乐观锁
@SpringBootTest
public class TestUserDao04 {
@Autowired
private UserDao userDao;
@Test
public void testUpdate(){
//1. 先查询数据
User user = userDao.selectById(3L);
//1.1修改数据
user.setPassword("6789");
//2.执行更新
userDao.updateById(user);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/acb08a87e03fb6b256dbd46db50569d8.png)
解释(注:以下的例子是视频例子以我的操作不同)
![](https://file2.kaopuke.com:8081/files_image/2023060822/7995ff45aaca166daa0401e4ccae5a33.png)
package com.itheima.test;
import com.itheima.bean.User;
import com.itheima.dao.UserDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
//演示乐观锁
@SpringBootTest
public class TestUserDao04 {
@Autowired
private UserDao userDao;
@Test
public void testUpdate(){
//1. 先查询数据
User user = userDao.selectById(3);
//1. 先查询数据
User user02 = userDao.selectById(3);
//1.1 修改数据
user.setPassword("888");
//1.2 执行更新
userDao.updateById(user);
user02.setPassword("0000");
userDao.updateById(user02);
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/e3ceae221728f3eeb9916d97c4ce8b41.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/90f4fbf41f9ea6118710cd1f2645c938.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/259572343621a7613211a0f8b7a3d472.png)
五、快速开发-代码生成器
问题导入
如果只给一张表的字段信息,能够推演出Domain、Dao层的代码?
1. MyBatisPlus提供模板
Mapper接口模板
![](https://file2.kaopuke.com:8081/files_image/2023060822/786dcb286fa25a92091ea9d7f3454b16.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/39dd09a7109867d0a2f7a6e18cbc46b8.png)
实体对象类模板
![](https://file2.kaopuke.com:8081/files_image/2023060822/72423e5efb5367aaf4eaa70a1c5dbdc6.png)
2. 工程搭建和基本代码编写
第一步:创建SpringBoot工程,添加代码生成器相关依赖,其他依赖自行添加
![](https://file2.kaopuke.com:8081/files_image/2023060822/536337e4f0571f333353fd17a400627b.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/629a796ea61bf065ab58aa4ddc9182f9.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/c6f89e4f8e9657f560a17e181e02bbc8.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/97e46c2841b64c9040106f6e37f32f3a.png)
![](https://file2.kaopuke.com:8081/files_image/2023060822/edcae2fa1c42cfb0a4b0860cbeb92c0b.png)
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!--代码生成器-->
<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>
![](https://file2.kaopuke.com:8081/files_image/2023060822/c459421a12ec79af025ce411fc22b211.png)
第二步:编写代码生成器类
![](https://file2.kaopuke.com:8081/files_image/2023060822/4798d31458e6b1571e65aa5a00bc6c3e.png)
@SpringBootTest
class Demo5CodeApplicationTests {
@Test
void contextLoads() {
//D:review_MyBatisPlusreview_MyBatisPlus_itheimamybatisplusdemo5_code
System.out.println(System.getProperty("user.dir"));
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/26e181c4f81ca1155de745c91ae7edae.png)
黑马笔记内容
package com.itheima;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
public class Generator {
public static void main(String[] args) {
//1. 创建代码生成器对象,执行生成代码操作
AutoGenerator autoGenerator = new AutoGenerator();
//2. 数据源相关配置:读取数据库中的信息,根据数据库表结构生成代码
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);
//3. 执行生成操作
autoGenerator.execute();
}
}
`package com.itheima;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Demo5CodeApplicationTests {
@Test
void contextLoads() {
//D:review_MyBatisPlusreview_MyBatisPlus_itheimamybatisplusdemo5_code
System.out.println(System.getProperty("user.dir"));
//创建代码生成器对象,执行生成代码操作
AutoGenerator autoGenerator = new AutoGenerator();
//数据源相关配置:读取数据库中的信息,根据数据库表结构生成代码
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/reggie?serverTimezone=UTC");
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("123456");
autoGenerator.setDataSource(dataSourceConfig);
//设置全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");
globalConfig.setOpen(false);
globalConfig.setAuthor("黑马程序员");
globalConfig.setFileOverride(true);
globalConfig.setMapperName("%sDao");
globalConfig.setIdType(IdType.ASSIGN_ID);
// autoGenerator.setGlobalConfig(globalConfig);
//包相关配置
PackageConfig packageInfo = new PackageConfig();
packageInfo.setParent("com.itheima");
packageInfo.setEntity("bean");
packageInfo.setMapper("dao");
autoGenerator.setPackageInfo(packageInfo);
//策略配置
StrategyConfig strategy = new StrategyConfig();
//strategy.setInclude("tbl_user");
strategy.setTablePrefix("tbl_");
strategy.setRestControllerStyle(true);
strategy.setEntityLombokModel(true);
//strategy.setLogicDeleteFieldName("deleted");
//strategy.setVersionFieldName("version");
autoGenerator.setStrategy(strategy);
autoGenerator.execute();
}
}
![](https://file2.kaopuke.com:8081/files_image/2023060822/6096a58ef7ca82e12f73d8f742006714.png)
说明:在资料中也提供了CodeGenerator代码生成器类,根据实际情况修改后可以直接使用。
3. 开发者自定义配置
设置全局配置
//设置全局配置
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); //设置是否启用lombok
autoGenerator.setStrategy(strategyConfig);
说明:在资料中也提供了CodeGenerator代码生成器类,根据实际情况修改后可以直接使用。
最后
以上就是缥缈路人为你收集整理的mybatisplus复习(黑马)的全部内容,希望文章能够帮你解决mybatisplus复习(黑马)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复