@TOC
乐观锁、悲观锁
乐观锁:十分乐观,他认为不会出现问题,无论干什么都不去上锁! 只会在数据提交的时候进行检验。 如果出现问题, 再次更新测试值(这个操作称为自旋)
CAS属于乐观锁;
乐观锁具体实现方式:
- 取出记录时,获取当前的version — version=1(此时相当于CAS中 获得旧预期值A=version )
- 更新时,带上这个version (查找数据库中 version是否为1的数据)
- 执行更新时, set version = newVersion where version = oldversion
- 如果version不对,则更新失败 (判断旧预期值A 与数据库中的V值是否相同,)
测试MP的乐观所锁插件
-
给数据库中增加Version字段,全默认为1;
-
更改pojo类
-
增加配置类
package com.hkvision.hire.Config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableLoadTimeWeaving;
/*
* @ClassName: MyBatiesPluseConfig
* @Copyright(C) 2019 杭州海康威视技术有限公司
* @Description:
* @author tangjing13
* @date 2021年33月19日
*/
@Configuration// 配置类
@EnableLoadTimeWeaving// 开启事务控制 (自动管理事务)
@MapperScan("com.hkvision.hire.mapper")
public class MyBatiesPluseConfig {
// 注册乐观锁插件 (从官网Copy的)
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
测试: 操作被中断的更新过程不执行
// 测试乐观:让操作被中断的更新操作不执行
@Test
void Version2(){
// 线程1
User user = userMapper.selectById(1);
user.setName("aoteman11111");
// 模拟另一个线程执行插队操作
User user2 = userMapper.selectById(1);
user.setName("大怪兽2222222");
userMapper.updateById(user2);
//自旋锁 多次尝试提交
userMapper.updateById(user); // 如果没有乐观锁、就会插队
}
分页
如何使用:
-
- 配置拦截器
@Bean
public MybatisPlusInterceptor PaginationInnerInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
- 2.使用
@Test
public void testPage(){
// 参数1 当前页
// 参数2 页面大小
Page<User> page = new Page<>(2,5);//第一页 每页5个
userMapper.selectPage( page,null);
page.getRecords().forEach(System.out::println);
page.getTotal(); // 获取页数
}
删除(物理删除、逻辑删除)
物理删除:从数据库中直接删除
逻辑删除:给数据库一个delete字段;为1搜寻出来;为0不可搜寻出来
逻辑删除配置:
1、数据库增加delete字段
2、pojo类属性字段加注解
3、配置.yaml
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logic-delete-field: delete # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
4、测试
// 逻辑删除
@Test
public void deleteTest(){
userMapper.deleteById(1);
}
使用条件构造器(Like、notlike,likeleft、likeright、beetween、order、)
//使用条件构造器
@Test
public void wrappertest(){
//查询 name、email不为空 、年龄>12;
QueryWrapper<User> Wrapper = new QueryWrapper<>();
Wrapper
.isNotNull("name")
.ge("age",12);
userMapper.selectList(Wrapper).forEach(System.out::println);
//根据名字查询
QueryWrapper<User> Wrapper1 = new QueryWrapper<>();
Wrapper
.eq("name","Tom");
User user = userMapper.selectOne(Wrapper); //查询一个
System.out.println(user.toString());
//查询between and 年龄20到30岁
QueryWrapper<User> Wrapper3 = new QueryWrapper<>();
Wrapper3.between("age",20,30);
userMapper.selectList(Wrapper3).forEach(System.out::println);
System.out.println("模糊查询");
//模糊查询 查询名字不带T
QueryWrapper<User> Wrapper4 = new QueryWrapper<>();
Wrapper4
.notLike( "name","T")
.likeLeft("name","e") //%e 通配符在左边
.likeRight("email","6")//查询邮箱时5开头
;
userMapper.selectList(Wrapper4).forEach(System.out::println);
//通过id进行排序
QueryWrapper<User> Wrapper5 = new QueryWrapper<>();
Wrapper5.orderByDesc("id");
userMapper.selectList(Wrapper5).forEach(System.out::println);
}
}
总结
东西肯定是不完整的、留着以后慢慢补充吧。