我们经常会被问道乐观锁和悲观锁!
乐观锁:顾名思义十分乐观,它总是认为不会出现问题,就不论干什么不去上锁,如果出现问题再次更新值测试.
悲观锁:顾名思义十分悲观,它认为总是出现问题,不论干什么都会上锁,再去操作.
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
测试Mybatis-Plus插件
-
给数据库增加Version字段
-
实体类加对应的字段
@Version //乐观锁Version注解
private Integer version;
- 注册主键
@EnableTransactionManagement
@Configuration //配置类
public class MybatisPlusConfig {
//注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
- 测试
//测试乐观锁成功
@Test
public void testOptimisticLocker(){
//1.查询用户信息
User user = userMapper.selectById(1L);
//2.修改用户信息
user.setAge(10);
user.setEmail("98765@qq.com");
//3.执行更新操作
userMapper.updateById(user);
}
//测试乐观锁失败 (多线程情况下)
@Test
public void testOptimisticLocker2(){
// 线程 1
User user = userMapper.selectById(1L);
user.setName("王五11111");
user.setAge(10);
user.setEmail("98765@qq.com");
//模拟另外一个线程2执行插队操作
User user2 = userMapper.selectById(1L);
user2.setName("王五22222");
user.setAge(10);
user.setEmail("98765@qq.com");
userMapper.updateById(user2);
//自旋锁来多次尝试提交
userMapper.updateById(user); //如果没有乐观锁就会覆盖插队线程2的值
}
查询操作
//测试查询
@Test
public void testSelectById() {
User user = userMapper.selectById(1L);
System.out.println(user);
}
//测试批量查询
@Test
public void testSelectByBatchId() {
List users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
//测试条件查询之一 使用Map操作
@Test
public void testSelectByBatchIds() {
HashMap map = new HashMap<>();
//自定义要查询的条件
map.put("name", "张三");
map.put("age", 22);
List users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
分页查询
分页在网站使用非常多
- 原始的limit 进行分页
- pageHelper第三方插件
- Mybatis_Plus 也内置了分页插件
如何使用
- 配置连接器组件
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
- 直接使用Page对象即可
//测试分页查询
@Test
public void testPage(){
//参数一: 当前页
//参数二: 页面大小
Page page = new Page<>(1,5);
userMapper.selectPage(page,null);
page.getRecords().forEach(System.out::println);
System.out.println(page.getTotal()); //查询数据的总数
}
删除操作
基本的删除操作
//测试删除
@Test
public void testDeleteById() {
userMapper.deleteById(1442391931556753413L);
}
// 通过ID,批量删除
@Test
public void testDeleteBatchId() {
userMapper.deleteBatchIds(Arrays.asList(1442391931556753411L, 1442391931556753412L));
}
// 通过Map 批量删除
@Test
public void testDeleteMap(){
HashMap map = new HashMap<>();
map.put("name","李四");
userMapper.deleteByMap(map);
}
逻辑删除
物理删除:从数据库中直接移除
逻辑删除:在数据库中没有被移除,而是通过一个变量来让它失效。
管理员可以查看被删除的记录,防止数据丢失,类似于回收站。
测试:
-
在数据表中增加一个deleted字段
-
实体类中增加属性
@TableLogic //逻辑删除
private Integer deleted;
- 配置
//逻辑删除组件
@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
- 测试删除
记录依旧在数据库,但是值已经发生了变化。
当我们再次查询这条数据的时候
查询的时候会自动过滤被逻辑删除的字段
我们在平时开发中,会遇到一些慢SQL。
作用:性能分析拦截器,用于输出每条SQL语句及其执行时间。
Mybatis-Plus提供了性能分析插件,如果超过这个时间就停止运行。
Wrapper
我们写一些复杂的SQL就可以用它来替代。
测试一:
@Test
void contextLoads() {
//查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12岁的
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.isNotNull("name").isNotNull("email").ge("age",12);
userMapper.selectList(wrapper).forEach(System.out::println); //和我们刚写的map对比
}
测试二:
@Test
void test2(){
//查询名字为Tom的,
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.eq("name","Tom");
User user = userMapper.selectOne(wrapper);//查询一行数据,出现多个结果使用List或者Map
System.out.println(user);
}
测试三
@Test
void test3(){
//查询年龄在20到三十岁之间的用户
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.between("age",20,30); //区间
Integer count = userMapper.selectCount(wrapper);//查询结果数
System.out.println(count);
}
测试四:
//模糊查询
@Test
void test4() {
// 查询名字里面不包含"n"的,并且email里面包含t的
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.notLike("name", "n").likeRight("email", "t");
List
测试五:
@Test
void test5(){
QueryWrapper wrapper = new QueryWrapper<>();
//id 在子查询中查出来
wrapper.inSql("id","select id from user where id<3");
List
测试六
@Test
void test6(){
QueryWrapper wrapper = new QueryWrapper<>();
//通过id进行排序
wrapper.orderByDesc("id");
List users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
代码自动生成器


