上篇我们说到,使用 MyBatisPlus 省去了 CRUD 的编写,极大的简化了开发。
接下来,继续说说 MyBatisPlus 的其他特性
查询操作
查询操作,有很多方法,这里列举了:根据 id 查询、根据 id 批量查询、map 查询
map 中存放的键值对,就表示了查询的条件
//下面是许多查询操作
@Test
public void testSelectById(){
User user = userMapper.selectById(1L);
}
//批量查询用户
@Test
public void testSelectBatchIds(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
//按条件查询,使用 map 查询
@Test
public void testSelectByMap(){
HashMap<String, Object> hashMap = new HashMap<>();
//map 里放的是查询的条件 查询名字是 Czx 的人的信息
hashMap.put("name","Czx");
//条件可以拼接,往进 put 一个,就是一个条件 WHERE name = ? AND age =
hashMap.put("age",200L);
List<User> users = userMapper.selectByMap(hashMap);
users.forEach(System.out::println);
}
MyBatisPlus 的分页插件
在配置类中增加配置
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
编写测试代码
Page 中的参数有两个:long current、long size。current 表示了当前页数,size 表示了每页数据个数
//分页插件
@Test
public void testPage(){
//selectPage(IPage<T> var1,Page 是 Ipage的实现类
// Page的参数有两个,long current, long size
// 第一个是当前页,
// 第二个是每页显示数据的个数
Page<User> userPage = new Page<>(1,5);
userMapper.selectPage(userPage,null);
userPage.getRecords().forEach(System.out::println);
System.out.println(userPage.getTotal()); //数据的总数
System.out.println(userPage.getCurrent()); //当前页数
}
实际上,MyBatisPlus 的分页底层采用的还是 limit
删除操作
删除与查询很类似,根据 id 删除、根据 id 批量删除、map删除
其中,map 的键值对就是删除的条件
//根据 id 删除
@Test
public void testDelete(){
userMapper.deleteById(1278951504018575369L);
}
//根据 id 批量删除
@Test
public void testDeleteBatchIds(){
userMapper.deleteBatchIds(Arrays.asList(1278951504018575367L,1278951504018575368L));
}
//使用 map 删除
@Test
public void testDeleteByMap(){
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("age",200);
userMapper.deleteByMap(hashMap);
}
逻辑删除
物理删除:从数据库中直接删除数据
逻辑删除:并没有在数据库中直接删除数据,而是通过一个变量,让这个数据失效
逻辑删除目的:防止数据的丢失,管理员可以看见删除的数据
1、更改数据库,增加 deleted 字段,默认为 0
2、同步实体类
给实体类中添加 deleted 字段和 @TableLogic 注解
@TableLogic
private Integer deleted;
3、配置 properties
默认为 0 ,是没有被删除的数据,1 是已删除的数据
# 配置逻辑删除
mybatis-plus.global-config.db-config.logic-not-delete-value=0
mybatis-plus.global-config.db-config.logic-delete-value=1
4、测试
//逻辑删除
@Test
public void testLogicDelete(){
userMapper.deleteById(1L);
}
我们来删除 1 号用户,发现数据并没有丢失,而是它的 deleted 字段改为了 1
实际上,逻辑删除这个操作,最终走的是更新
我们原来已经写过查询所有用户的代码,现在再来查询所有的用户,发现 1 号用户已经查不出来了
在查的时候,也会自动过滤逻辑删除的字段
性能分析插件
性能分析插件是用来测试代码运行时长的插件,当我们规定,查询时间小于 100ms 的代码才是可用的,这时,就需要用到性能分析插件。
1、在配置类中增加配置
//性能分析插件
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100); //设置 sql 执行时间为最大 100 ms,超过报错
performanceInterceptor.setFormat(true); //格式化 sql 语句,看起来看清晰
return performanceInterceptor;
}
2、配置开发环境
dev 是开发环境,test 是测试环境,我们现在切换到开发环境下测试
# 配置开发环境
spring.profiles.active=dev
3、测试
我们将性能更改为,运行时间大于 1ms ,这个查询是不合理的
performanceInterceptor.setMaxTime(1); //设置 sql 执行时间为最大 1 ms,超过报错
//性能分析插件
@Test
public void testPerformanceInterceptor() {
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
查询所有用户的时间是 28ms ,超过了 1ms ,所以停止了运行,并报错
Wrapper 构造器
wrapper ,一些复杂的 sql 语句就使用它来代替
wrapper 是一个接口,我们经常使用它下面的实现类,QueryWrapper
重建测试类,来测试 wrapper
1、非空,大于 测试
@Test
void test1() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.isNotNull("name") //姓名不为空
.isNotNull("age") //年龄不为空
.ge("age",13); //age 大于 13 的
userMapper.selectList(wrapper);
}
2、匹配测试
查询姓名是 Billie 这个人的信息
@Test
void test2() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.eq("name","Billie"); //匹配
User user = userMapper.selectOne(wrapper);
System.out.println(user);
}
3、条件测试
查找年龄在 20 ~ 30 之间的人的信息
@Test
void test3() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.between("age",20,30);
Integer integer = userMapper.selectCount(wrapper);
System.out.println(integer);
}
4、模糊查询
查询名字中没有 e 的人,likeright 相当于 t% 这个查询条件,likeleft 就相当于 %t 这样
@Test
void test4() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.notLike("name","e")
.likeRight("email","t");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
5、子查询
//子查询
@Test
void test5() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.inSql("id","select id from user where id<3");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
6、排序
Desc 降序排列,Asc 升序排列
根据 id 降序排列
@Test
void test6() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.orderByDesc("id");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
根据 id 升序排列
@Test
void test6() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.orderByAsc("id");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
wrapper 构造器的方法还有很多,不仅仅局限于上面几种
至此,MyBatisPlus 中常用的技术已经介绍完毕
我们下篇见 (∩_∩)~