MybatisPlus乐观锁
MybatisPlus乐观锁
基于这篇博客修改
理解
主要解决的问题:丢失更新问题
图解:
数据库添加version字段
user类
注意:属性添加@Version注解
package com.xiang.pojo;
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* Created by IntelliJ IDEA.
* User: xiang
* Date: 2021/10/21 2:50
*/
/**
* `id` int NOT NULL AUTO_INCREMENT,
* `username` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
* `sex` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
* `age` int NULL DEFAULT NULL,
* `birthday` date NULL DEFAULT NULL,
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
// @TableId(type = IdType.ID_WORKER) //数字类型的id使用,当类型为Long时默认使用,生成19位的Id值,
// @TableId(type = IdType.ID_WORKER_STR)//字符串类型的id使用,需要写明注解,生成19位的Id值
//同时需要设置数据库的字段id的类型为Bigint,因为int的长度只有11位
private Long id;
private String username;
private String sex;
private int age;
private Date birthday;
/***
* 使用mybatisPlus自动填充时间
*
* 第一:添加注解
* 第二:实现MetaObjectHandler接口
* 第三:重写inserFill和updateFill方法
* 第四:调用setFieldValByName方法
*/
@TableField(fill = FieldFill.INSERT)//进行添加操作时有值
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)////进行添加和修改操作时有值
private Date updateTime;
/**
* 添加version属性,注意添加@Version注解
* 同时使用TableField设置初始值为1
*/
@TableField(fill = FieldFill.INSERT)
@Version
private Integer version;
}
MeatObjectHandler类
package com.xiang.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* Created by IntelliJ IDEA.
* User: xiang
* Date: 2021/10/22 22:50
*/
@Component
public class MeatObjectHandler implements MetaObjectHandler {
@Override
//使用MybatisPlus实现添加操作时,该方法会执行
public void insertFill(MetaObject metaObject) {
//参数:需要设置的属性;设置的时间;元数据(理解:表中的数据)
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
// //设置版本号的初始值为1
this.setFieldValByName("version", 1, metaObject);
}
@Override
//使用MybatisPlus实现修改操作时,该方法会执行
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
创建MybatisPlusConfig配置类
- 将MapperScan注解从启动类移动到配置类
- 乐观锁插件可以不用记忆,下次直接复制
package com.xiang.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Created by IntelliJ IDEA.
* User: xiang
* Date: 2021/10/23 0:07
*/
@MapperScan("com.xiang.mapper")
//添加扫描注解,写入mapper的路径,否则会找不到接口并报错
@Configuration
public class MybatisPlusConfig {
//乐观锁插件
@Bean
public OptimisticLockerInterceptor OptimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
测试类
package com.xiang;
import com.xiang.mapper.UserMapper;
import com.xiang.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: xiang
* Date: 2021/10/23 0:11
*/
@SpringBootTest
public class VersionTest {
@Autowired
UserMapper userMapper;
/**
* 对 MybatisPlus乐观锁 进行测试
*/
@Test
/**
* 添加
*/
void insertVersion() {
User user = new User();
user.setUsername("tom");
user.setSex("男");
user.setBirthday(new Date());
user.setAge(22);
int insert = userMapper.insert(user);
if (insert > 0) {
System.out.println("添加成功");
} else {
System.out.println("fail");
}
List<User> list = userMapper.selectList(null);
for (User listUser : list) {
System.out.println(listUser);
}
}
@Test
/**
* 更新
*/
void updateVersion(){
User user = userMapper.selectById(1451573602674176001l);
user.setAge(18);
int i = userMapper.updateById(user);
if (i>0){
System.out.println("更新成功");
}else {
System.out.println("更新失败");
}
List<User> list = userMapper.selectList(null);
for (User listUser : list) {
System.out.println(listUser);
}
}
}
运行结果
添加
JDBC Connection [HikariProxyConnection@461001437 wrapping com.mysql.cj.jdbc.ConnectionImpl@7f93dd4e] will not be managed by Spring
==> Preparing: INSERT INTO user ( id, username, sex, age, birthday, create_time, update_time, version ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )
==> Parameters: 1451590215817437185(Long), tom(String), 男(String), 22(Integer), 2021-10-23 00:44:11.301(Timestamp), 2021-10-23 00:44:11.35(Timestamp), 2021-10-23 00:44:11.35(Timestamp), 1(Integer)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@57f9b467]
添加成功
JDBC Connection [HikariProxyConnection@1973471376 wrapping com.mysql.cj.jdbc.ConnectionImpl@7f93dd4e] will not be managed by Spring
==> Preparing: SELECT id,username,sex,age,birthday,create_time,update_time,version FROM user
==> Parameters:
<== Columns: id, username, sex, age, birthday, create_time, update_time, version
<== Row: 1, xiang, 男, 18, 2021-10-03, null, null, null
<== Row: 559, 小向, 男, 18, 2021-10-04, null, null, null
<== Row: 602, admin, 女, 18, 2021-10-20, null, null, null
<== Row: 603, testbox, 女, 18, 2021-10-02, null, null, null
<== Row: 604, 小一, 男, 18, 2021-10-16, null, null, null
<== Row: 605, 小二, 女, 18, null, null, null, null
<== Row: 607, 小四, 女, 21, null, null, null, null
<== Row: 609, 小五, 女, 0, null, null, null, null
<== Row: 1451097869404868609, 向某, 男, 0, null, null, null, null
<== Row: 1451098975287668738, 周某, 男, 0, null, null, null, null
<== Row: 1451572730934198273, 向某某, 女, 18, 2021-10-22, 2021-10-22 23:34:43, 2021-10-23 00:18:41, null
<== Row: 1451573602674176001, 向向, 女, 18, 2021-10-22, 2021-10-22 23:38:10, 2021-10-22 23:46:10, null
<== Row: 1451589057287688194, json, 男, 18, 2021-10-23, 2021-10-23 00:39:35, 2021-10-23 00:40:19, 2
<== Row: 1451590215817437185, tom, 男, 22, 2021-10-23, 2021-10-23 00:44:11, 2021-10-23 00:44:11, 1
<== Total: 14
更新
JDBC Connection [HikariProxyConnection@629016615 wrapping com.mysql.cj.jdbc.ConnectionImpl@58740366] will not be managed by Spring
==> Preparing: UPDATE user SET username=?, sex=?, age=?, birthday=?, create_time=?, update_time=?, version=? WHERE id=? AND version=?
==> Parameters: tom(String), 男(String), 18(Integer), 2021-10-23 00:00:00.0(Timestamp), 2021-10-23 00:44:11.0(Timestamp), 2021-10-23 00:48:11.516(Timestamp), 2(Integer), 1451590215817437185(Long), 1(Integer)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@a50d709]
更新成功
JDBC Connection [HikariProxyConnection@1071245351 wrapping com.mysql.cj.jdbc.ConnectionImpl@58740366] will not be managed by Spring
==> Preparing: SELECT id,username,sex,age,birthday,create_time,update_time,version FROM user
==> Parameters:
<== Columns: id, username, sex, age, birthday, create_time, update_time, version
<== Row: 1, xiang, 男, 18, 2021-10-03, null, null, null
<== Row: 559, 小向, 男, 18, 2021-10-04, null, null, null
<== Row: 602, admin, 女, 18, 2021-10-20, null, null, null
<== Row: 603, testbox, 女, 18, 2021-10-02, null, null, null
<== Row: 604, 小一, 男, 18, 2021-10-16, null, null, null
<== Row: 605, 小二, 女, 18, null, null, null, null
<== Row: 607, 小四, 女, 21, null, null, null, null
<== Row: 609, 小五, 女, 0, null, null, null, null
<== Row: 1451097869404868609, 向某, 男, 0, null, null, null, null
<== Row: 1451098975287668738, 周某, 男, 0, null, null, null, null
<== Row: 1451572730934198273, 向某某, 女, 18, 2021-10-22, 2021-10-22 23:34:43, 2021-10-23 00:18:41, null
<== Row: 1451573602674176001, 向向, 女, 18, 2021-10-22, 2021-10-22 23:38:10, 2021-10-22 23:46:10, null
<== Row: 1451589057287688194, json, 男, 18, 2021-10-23, 2021-10-23 00:39:35, 2021-10-23 00:40:19, 2
<== Row: 1451590215817437185, tom, 男, 18, 2021-10-23, 2021-10-23 00:44:11, 2021-10-23 00:48:12, 2
<== Total: 14