乐观锁插件使用
乐观锁:顾名思义,十分乐观,总是认为不会出现问题,无论什么操作都不会上锁,如果出现问题,再去更新值测试;
悲观锁:十分悲观,总是认为会出现问题,无论什么操作都会上锁,再去进行操作。
乐观锁实现方式:
- 取出记录时,获取当前version,select vesion
- 执行更新操作时,带上version,set version=newVersion where version=oldVersion
- 如果version不对,则更新失败
测试乐观锁插件
1、给数据库添加version字段
2、实体类中添加对应的字段
@Version //乐观锁version注解
private int version;
3、注册乐观锁插件
//扫描 mapper 文件夹
@MapperScan("com.zgy.mapper")
@EnableTransactionManagement
@Configuration //配置类
public class MyConfig {
//注册乐观锁插件
/**
* 旧版 mybatis-plus-boot-starter依赖为3.0.5版本时可使用
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
/**
* 新版 mybatis-plus-boot-starter依赖为3.5.2版本时可使用
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}
4、测试使用
//单线程情况下测试乐观锁
@Test
public void testOptimisticLocker() {
User user = userMapper.selectById(1L);
user.setName("zgy111");
user.setAge(20);
int result = userMapper.updateById(user);
System.out.println(result);
}
//模拟多线程情况下测试乐观锁
@Test
public void testOptimisticLocker2() {
User user = userMapper.selectById(2L);
user.setName("zgy111111");
user.setEmail("139739@qq.com");
User user2 = userMapper.selectById(2L);
user2.setName("zgy222222");
user2.setEmail("1397395869@qq.com");
//更新user2
userMapper.updateById(user2);
//由于version被修改,导致user更新失败
userMapper.updateById(user);
}
分页插件使用
分页查询方式:
1、原始的limit进行分页;
2、PageHelper第三方插件;
3、使用MP内置插件
测试MP内置分页插件:
1、注册分页插件
/**
* 旧版 mybatis-plus-boot-starter依赖为3.0.5版本时可使用
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
}
/**
* 新版 mybatis-plus-boot-starter依赖为3.5.2版本时可使用
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
2、直接使用page对象即可!
//测试分页查询
@Test
public void testPage() {
//参数1、当前页;参数2、页面大小
Page<User> page = new Page<>(1, 5);
userMapper.selectPage(page, null);
//输出当前页5条数据
page.getRecords().forEach(System.out::println);
//输出总数
System.out.println(page.getTotal());
}
逻辑删除
物理删除:数据从数据库中直接删除
逻辑删除:数据在数据库中没有被删除,而是通过一个变量让它失效,deleted=0 => deleted=1
管理员可以在数据库中查看被删除的数据,防止数据的丢失,类似于回收站的作用。
测试逻辑删除:
1、新版(mybatis-plus-boot-starter依赖为3.5.2版本)操作
(1)、数据库中添加deleted字段;
(2)、实体类中添加对应的字段(添加逻辑删除注解)
@TableLogic
@TableField(value = "deleted") //新版需要添加此注解
private Integer deleted;
(3)、配置
#配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
2、旧版(mybatis-plus-boot-starter依赖为3.0.5版本)操作
(1)、数据库中添加deleted字段(同上);
(2)、实体类中添加对应的字段;
@TableLogic
private Integer deleted;
(3)、配置逻辑删除组件
/**
* 逻辑删除组件
* @return
*/
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
#配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
3、测试逻辑删除
性能分析插件
在平时地开发过程中,难免会设计一些慢sql,通常需要测试解决。
MP提供了性能分析插件,如果执行语句超过所设定的时间就会停止运行。
使用性能分析插件可以帮助我们提高效率!!!
作用:性能分析拦截器,用于输出每条执行的sql语句以及执行语句所耗费的时间。
该插件3.2.0以上版本移除。官方推荐使用第三方扩展,执行SQL分析打印的功能
测试插件:
1、配置开发环境或测试环境
#设置开发环境
spring.profiles.active=dev
2、注册性能分析插件
/**
* sql执行效率插件
* @return
*/
@Bean
@Profile({"dev", "test"}) //设置dev test环境开启,保证效率
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
//设置SQL执行的最大时间为20ms,如果超过了则不执行
performanceInterceptor.setMaxTime(20);
//是否开启SQL语句格式化支持
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
3、测试插件使用
如果没超过20ms,则正常执行
如果超过20ms,则停止执行,抛出异常
@Test
public void testSelectById() {
//查询一位用户
User user = userMapper.selectById(1L);
System.out.println(user);
}
条件构造器
wrapper:十分重要
在开发过程中如果需要编写复杂的SQL语句,可以使用条件构造器替代
测试条件构造器:
1、测试一:
查询姓名和邮箱不为空,并且年龄大于等于24
@Test
public void test1() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.isNotNull("name")
.isNotNull("email")
.ge("age", 24);
List<User> userList = userMapper.selectList(wrapper);
userList.forEach(System.out::println);
}
2、测试二:
查询名字为Bob的用户
@Test
public void test2() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "Bob");
User user = userMapper.selectOne(wrapper);
System.out.println(user);
}
3、测试三:
查询年龄在20到30区间内的用户数量
@Test
public void test3() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age", 20, 30);
Integer count = userMapper.selectCount(wrapper);
System.out.println(count);
}
4、测试四:模糊查询
查询姓名中不含g并且邮箱以t开头的用户
@Test
public void test4() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.notLike("name", "g")
.likeRight("email", "t");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
5、测试五:子查询
@Test
public void test5() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id", "select id from user where id < 2");
List<Object> objects = userMapper.selectObjs(wrapper);
objects.forEach(System.out::println);
}
6、测试六:
通过id降序排列
@Test
public void test6() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
List<User> userList = userMapper.selectList(wrapper);
userList.forEach(System.out::println);
}