前言
乐观锁的原理白话描述:创建表时我们给每条数据来创建一个version 版本号字段,它可以是 int 、DateTime 等类型,当我们进行更新操作之前,先把version字段取出,然后更新的时候把这个字段作为条件来判断,是否有其他更新操作已经操作过此条数据。
实现案例
假设前提:
spring boot
Mybatis-plus
都已经配置好。
1.配置注册到bean中
这里要说明一下,3.4 之前的版本使用的是 OptimisticLockerInterceptor ,3.4以后的版本使用MybatisPlusInterceptor 。
package com.example.rabbitmq.mqConfig;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
public class MyBatisPlusConfig {
//乐观锁配置, 3.4以前的版本使用拦截器配置
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
//乐观锁配置 3.4以后弃用了 OptimisticLockerInterceptor 拦截器,需要使用 MybatisPlusInterceptor
/**
@Bean
public MybatisPlusInterceptor optimisticLockerInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
*/
// 旧版 -- 分页配置
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
return paginationInterceptor;
}
}
2.实体类
@Version 注解标注在实体类版本号字段上,数据库表中的 version 字段可以设置为int 类型,默认值为 1
package com.example.rabbitmq.pojo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import java.util.List;
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
@Version
private int version;
}
4.枚举类
package com.example.rabbitmq.constant;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import java.io.Serializable;
import java.util.Objects;
public enum SexDesc implements Serializable {
MAN(0,"男"),
MAS(1,"女");
@EnumValue
private int code;
@JsonValue
private String desc;
SexDesc(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@JsonCreator
public static SexDesc getByCode(int code) {
for (SexDesc value : SexDesc.values()) {
if (Objects.equals(code, value.getCode())) {
return value;
}
}
return null;
}
}
4.乐观锁使用
@Test
void testUser(){
//乐观锁基本实现
User user = userMapper.selectById(1L);//1.先查
user.setEmail("54@qq.com");//变更值
int i = userMapper.updateById(user);//2、提交变更
System.out.println(i);
}
捕捉到的语句:
5.其他示例
package com.example.rabbitmq;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.rabbitmq.mapper.UserMapper;
import com.example.rabbitmq.pojo.User;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import net.minidev.json.JSONUtil;
import org.apache.ibatis.session.RowBounds;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@SpringBootTest
class RabbitmqApplicationTests {
@Autowired(required = false)
UserMapper userMapper;
@Test
void contextLoads() {
System.out.println("TEST");
}
@Test
void testDeci(){
BigDecimal bigDecimal01 = new BigDecimal("100.0");
int bigDeci=12;
BigDecimal add = bigDecimal01.add(new BigDecimal(bigDeci));//加法
String uuId = UUID.randomUUID().toString().replace("-", "");
System.out.println(uuId);
}
@Test
void testUser(){
// List<User> users = userMapper.selectList(null);//查询
// users.forEach(System.out::println);
//1、乐观锁基本实现
// User user = userMapper.selectById(1L);
// user.setEmail("54@qq.com");
// int i = userMapper.updateById(user);
// System.out.println(i);
//2、枚举
// List<User> users = userMapper.selectList(null);//查询
// users.forEach(System.out::println);
//3、删除、
// int i = userMapper.deleteById(1L);
// System.out.println(i);
// 4、分页
QueryWrapper<User> wrapper = new QueryWrapper<>();
//条件构造器
wrapper.ge("age",26);
// 分页 参数 long current 当前页, long size 每页页数
Page<User> page = new Page<>(1, 2);
IPage<User> userIPage = userMapper.selectPage(page, wrapper);
System.out.println("总条数"+userIPage.getTotal());
System.out.println("总页数"+userIPage.getPages());
//分页
// QueryWrapper<User> wrapper = new QueryWrapper<>();
// wrapper.ge("age",26);
// //这里的参数需要注意,必须是 Map<String,Object> 集合
// Page<Map<String,Object>> page = new Page<>(1, 2);
// IPage<Map<String,Object>> userIPage = userMapper.selectMapsPage(page, wrapper);
// System.out.println("总条数"+userIPage.getTotal());
// System.out.println("总页数"+userIPage.getPages());
}
//分页
@Test
public void selectPage() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ge("age",26);
//这里的参数需要注意,必须是 Map<String,Object> 集合
Page<Map<String,Object>> page = new Page<>(1, 2);
IPage<Map<String,Object>> userIPage = userMapper.selectMapsPage(page, wrapper);
System.out.println("总条数"+userIPage.getTotal());
System.out.println("总页数"+userIPage.getPages());
}
}