当前位置: 首页 > article >正文

mybatisplus使用OptimisticLockerInnerInterceptor实现版本号乐观锁

OptimisticLockerInnerInterceptor 介绍

当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:

取出记录时,获取当前 version
更新时,带上这个 version
执行更新时, set version = newVersion where version = oldVersion
如果 version 不对,就更新失败。

创建项目

创建项目

引入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.7</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

创建数据表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`
(
    id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    version INT not NULL DEFAULT 0 COMMENT '版本年龄',
    PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

DELETE FROM user;
 
INSERT INTO user (id, name, age, email,version) VALUES
(1, 'Jone', 18, 'test1@baomidou.com',0),
(2, 'Jack', 20, 'test2@baomidou.com',0),
(3, 'Tom', 28, 'test3@baomidou.com',0),
(4, 'Sandy', 21, 'test4@baomidou.com',0),
(5, 'Billie', 24, 'test5@baomidou.com',0);

application.yml配置

server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://XXX:63306/user
    username: 
    password: 

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

项目结构

配置乐观锁拦截器

package com.sky.mybatisversiondemo.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

创建实体类

version字段需要添加@Version注解表名是版本号字段
package com.sky.mybatisversiondemo.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;


@Data
public class User {
    /**
     * 主键ID
     */
    @TableId(value = "id")
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 邮箱
     */
    private String email;
    /**
     * 版本号
     */
    @Version
    private Integer version;

}

创建mapper

package com.sky.mybatisversiondemo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sky.mybatisversiondemo.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

创建service

这里利用了mybatisPlus的特性,提供了一些默认的查询。

UserService

package com.sky.mybatisversiondemo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.sky.mybatisversiondemo.entity.User;

public interface UserService extends IService<User> {
}
UserServiceImpl
package com.sky.mybatisversiondemo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.mybatisversiondemo.entity.User;
import com.sky.mybatisversiondemo.mapper.UserMapper;
import com.sky.mybatisversiondemo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

创建返回包装类BaseResponse

package com.sky.mybatisversiondemo.vo;

import lombok.Data;

@Data
public class BaseResponse<T> {
    protected int code = 0;
    protected String message = "成功";

    protected T data;

    public BaseResponse(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public static <T> BaseResponse of(T data) {
        BaseResponse<T> response = new BaseResponse();
        response.setData(data);
        return response;
    }
    public BaseResponse() {
    }
}

创建UserController

package com.sky.mybatisversiondemo.controller;

import com.sky.mybatisversiondemo.entity.User;
import com.sky.mybatisversiondemo.service.UserService;
import com.sky.mybatisversiondemo.vo.BaseResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/list")
    public BaseResponse list(){
        List<User> list = userService.list();
        return BaseResponse.of(list);
    }

    @GetMapping("/ById")
    public  BaseResponse ById(Integer id){
        User user = userService.getById(id);
        if (user != null){
            return BaseResponse.of(user);
        }else {
            return new BaseResponse(500,"fail");
        }
    }

    /**
     * 插入学生信息
     * @param user
     */
    @PostMapping("/insert")
    public BaseResponse insertInfo(@RequestBody User user){
        boolean save = userService.save(user);
        if (save){
            return BaseResponse.of(save);
        }
        return new BaseResponse(500,"fail");
    }

    /**
     * 根据id更新学生表信息
     * @param user
     */
    @PutMapping("/update")
    public BaseResponse updateById(@RequestBody User user){
        boolean save = userService.updateById(user);
        if (save){
            return BaseResponse.of(save);
        }
        return new BaseResponse(500,"fail");
    }

    /**
     * 根据id删除学生信息
     * @param id
     */
    @DeleteMapping("/delete")
    public BaseResponse deleteById(String id){
        boolean b = userService.removeById(id);
        if (b){
            return BaseResponse.of(b);
        }
        return new BaseResponse(500,"fail");
    }

}

测试

查询

修改

修改是自动增加版本号,并且会增加版本号的判断,只有版本号一致才能修改成功。

日志

==>  Preparing: UPDATE user SET name=?, age=?, email=?, version=? WHERE id=? AND version=?
==> Parameters: Jone(String), 18(Integer), test1@baomidou.com(String), 1(Integer), 1(Long), 0(Integer)
<==    Updates: 1

修改后再查询 

此时版本号增加到1

再次按版本号0修改 

修改失败,因为版本号已经增加到了1,实现了乐观锁功能。

如果开发中遇到这种因为乐观锁修改失败的,则可以直接报错,或者再次查询数据后重试。推荐直接报错,修改失败,请重试。

修改时不传入版本号

则可以直接修改成功 ,但是修改后版本号不会增加,不推荐不传入版本号的修改。

日志

==>  Preparing: UPDATE user SET name=?, age=?, email=? WHERE id=?
==> Parameters: Jone(String), 18(Integer), test1@baomidou.com(String), 1(Long)
<==    Updates: 1


http://www.kler.cn/a/291496.html

相关文章:

  • 追风赶月莫停留,平芜尽处是春山—记一次备考经历(下)
  • Qt creator ,语言家功能缺失解决方法
  • 重温设计模式--单例模式
  • 【GO环境安装】mac系统+GoLand使用
  • Oracle Database 21c Express Edition数据库 和 Sqlplus客户端安装配置
  • 基于Springboot + vue实现的汽车资讯网站
  • 七月刚入职字节跳动的测试开发面试题,附答案
  • SpringCloud Alibaba】(十三)学习 RocketMQ 消息队列
  • Linux内核编程(十五)网络设备驱动
  • Transforms的常见用法
  • ARM的寄存器组织
  • 深度学习--机器学习相关(1)
  • 游戏:科技强国的璀璨星芒与经济增长新动力
  • Linux中的echo命令
  • LSPosed 模块开发入门和踩的坑
  • 游戏语音交流,求推荐第三方IM服务?增加玩家体验!
  • 如何阅读PyTorch文档及常见PyTorch错误
  • MLM:多模态大型语言模型的简介、微调方法、发展历史及其代表性模型、案例应用之详细攻略
  • JavaEE(2):前后端项目之间的交互
  • King’s LIMS 实验室信息管理系统:引领实验室数字化转型的创新力量
  • plc1200 weiluntong001
  • Tomato靶机通关攻略
  • sci文章录用后能要求删除其中一位作者吗?
  • 【Linux】在 bash shell 环境下,当一命令正在执行时,按下 control-Z 会?
  • [Java]SpringBoot业务代码增强
  • # 利刃出鞘_Tomcat 核心原理解析(十)-- Tomcat 性能调优--1