开篇
-
MyBatiesPlus(简称MP)是基于MyBatis框架基础上开发的增强工具,旨在简化开发,、提高效率。
-
开发方式
- 基于MyBatis使用MyBatisPlus
- 基于Spring整合MyBatisPlus
- 基于SpringBoot整合MyBatisPlus
-
回顾SpringBoot整合MyBatis
- 创建SpringBoot工程
- 勾选配置使用技术
- 设置dataSource相关属性(JDBC参数)
- 定义数据层接口映射配置
-
mybatis官网:https://mybatis.net.cn/
-
mybatis-plus官网:https://baomidou.com/
入门案例
依赖
这个技术只选MySQL Driver
建立工程之后,添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
标准数据层开发
工具
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
lombok依赖,可以使用@Data简化 POJO实体类开发,省去set、get、有无参构造器、toString等方法的书写
标准数据层开发
配置application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC
password: 527168zhao
username: root
User类
@Data
public class User {
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
}
UserDao接口
@Mapper
public interface UserDao extends BaseMapper<User> {
// 直接extends BaseMapper<User>,不用写详细方法
}
测试类
@SpringBootTest
class MybatisplusApplicationTests {
@Autowired
private UserDao userDao;
@Test
void contextLoads() {
List<User> users = userDao.selectList(null);
System.out.println(users);
}
@Test
void testSave(){
User user = new User();
user.setName("zhm");
user.setPassword("527168");
user.setAge(21);
user.setTel("465465464");
userDao.insert(user);
}
@Test
void testDelete(){
int deleteById = userDao.deleteById(1582602844478439426L);
}
}
标准分页功能制作
- 测试类中
@Test
void testGetByPage() {
IPage page = new Page(1, 2);
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());
}
- 做一个配置类,也就是分页的拦截器
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//定义一个拦截器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//添加具体拦截器
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
- 增加配置,application.yml中。这个是加日志的 标准输出StdOutImpl
#开启mp的日志 输出到控制台
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
DQL编程控制
取消日志
- Spring 和 MybatisPlus 图标取消
spring:
main:
banner-mode: off
mybatis-plus:
global-config:
banner: false
- 日志
在resources中创建一个空的logback.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
</configuration>
条件查询
- MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完后曾查询条件的组合
三种形式
- Wrapper抽象类的实现类QueryWrapper
@Test
void testGetAll1() {
//Wrapper抽象类 QueryWrapper抽象类的实现类,用于按条件查询
QueryWrapper qw = new QueryWrapper<>();
qw.lt("age",18);// lt大于, age<18 。gt大于
List<User> userList = userDao.selectList(qw);
System.out.println(userList);
}
- 也是QueryWrapper,但是条件添加改成了Lambda表达式 (为了属性不易写错)
@Test
void testGetAll2() {
//Wrapper抽象类 QueryWrapper抽象类的实现类,用于按条件查询
//需要写泛型
QueryWrapper<User> qw = new QueryWrapper<User>();
qw.lambda().lt(User::getAge,18);
List<User> userList = userDao.selectList(qw);
System.out.println(userList);
}
- 直接使用LambdaQueryWrapper类,基于两种写法的综合写法
@Test
void testGetAll3() {
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.lt(User::getAge,18).gt(User::getAge,1);
lqw.lt(User::getAge,18).or().gt(User::getAge,19);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
条件查询null判定
场景:
现建立一个
@Data
public class UserQuery extends User {
private Integer age2; //相当于定一个上限,原来的User.age是下限
}
测试类中
@Test
void testGetAll4() {
UserQuery uq = new UserQuery();
uq.setAge(10); //下限
uq.setAge2(30); //上限,如果上下限有没设的情况
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//先进行判定,第一个判断语句true的情况下,拦截器才会添加后续条件
lqw.gt(null != uq.getAge(),User::getAge,uq.getAge());
lqw.lt(null != uq.getAge2(),User::getAge,uq.getAge2());
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
查询投影(想查看哪些属性,或者统计数据...等等)
- Lambda表达式查询
@Test
void testGetAll5() {
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.select(User::getId, User::getName, User::getAge);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 字符串查询
@Test
void testGetAll6() {
QueryWrapper<User> lqw = new QueryWrapper<>();
lqw.select("id", "name", "age", "tel");
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 特殊查询 这里需要使用 userDao.
@Test
void testGetAll7() {
QueryWrapper<User> lqw = new QueryWrapper<>();
//统计count(*) 显示为count(*)=4,添加 as count别名,显示为count=4
lqw.select("count(*) as count");
lqw.groupBy("tel");//分组查询
//这里使用userDao.selectMaps(),key = count(*),value = 4
//如果用selectList(),根据泛型,返回的是User类,无法接收count
List<Map<String, Object>> userList = userDao.selectMaps(lqw);
System.out.println(userList);
}
查询条件
- 范围匹配
@Test
void test() {
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//范围查询: lt le gt ge eq between < <= > >= == (,)
lqw.between(User::getAge,10,30);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 模糊匹配
@Test
void test() {
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.like(User::getName,"J");
//lqw.likeRight(User::getName,"J"); //J%
//lqw.likeLeft(User::getName,"J"); //%J
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
- 空判定
- 包含性匹配
- 分组
- 排序
- ...
- 官方文档:https://baomidou.com/pages/10c804/
字段映射与表名映射
- 数据库字段与POJO类对应变量名不相符时,数据库是已经定义好的字段,所以建议修改后者
假如,数据库字段为pwd,POJO变量名为password,此时可以使用@TableField(value = "")注解
@TableField(value="pwd")
private String password;
- POJO类中出现了数据库没有的字段,这时使用@TableField(exist = false)
@TableField(exist = false)
private Integer online;
-
采用默认查询开放了更多的字段查看权限 比如密码,需要告诉MP,这个属性不能被查询,使用@TableField(select = false)
-
表名与POJO名不符,使用注解TableName("")
场景:数据库中有表 user_db
@TableName("user_db")
public class User{
}
- 对于表明如果有前缀统一 比如都死"db_"开头的,可以直接在全局配置里配置:
mybatis-plus:
global-config:
db-config:
table-prefix: db_
id生成策略
- 不同的表应用不同的id生成策略
- 日志:自增(1,2,3,...)
- 购物订单:特殊规则(FQ23948AK3843)
- 外卖单:关联地区日期等信息(10 04 20200314 34 91)
- 关系表:可省略id
官方文档:https://baomidou.com/pages/223848/#idtype
可以全局配置:application.yml
mybatis-plus:
global-config:
banner: false
db-config:
id-type: assign_id
多记录操作(删除与查询)
@Test
void test() {
//删除id为5 和 6
List<Long> list = new ArrayList<Long>();
list.add(6L);
list.add(5L);
userDao.deleteBatchIds(list);
//查询id为1 和 2
List<Long> list1 = new ArrayList<Long>();
list.add(1L);
list.add(2L);
userDao.selectBatchIds(list1);
}
逻辑删除
不是真正的删除,只是为数据设置是否可用状态字段,删除时设置状态字段为不可用字段,数据保留在数据库中
在POJO类中
// 第一个值代表存在,第二个值代表已删除
@TableLogic(value = "0",delval = "1");
private Integer deleted;
测试中
userDao.deleteById(1L);
实际上在数据库中,执行的是update语句,更新了记录的deleted字段为1,代表已删除
查询时,全局查询也不会查到deleted = 1的记录
也就是说:
- value = "0" 影响的是查询,查的都是deleted=0的记录
- delval = "1" 影响的是删除,实质上是更新为deleted=1
全局配置(省去注解)
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
- 表示删除的字段名
- 被删除,值
- 未删除,值
乐观锁
代码生成器
依赖:
<!--代码生成器-->
<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>
标签:userDao,框架,lqw,userList,User,new,println,MybatisPlus
From: https://www.cnblogs.com/mlstudyjava/p/16806493.html