Java教程

关于SpringBoot整合MyBatis-Plus乐观锁不生效的问题解决方案

本文主要是介绍关于SpringBoot整合MyBatis-Plus乐观锁不生效的问题解决方案,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

关于SpringBoot整合MyBatis-Plus乐观锁不生效的问题解决方案

SpringBoot整合Myabtis-Plus

在与官网配置一致的情况下依旧无法生效,如下整合mybatis-plus

1、依赖导入

<!--        mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3.4</version>
</dependency>

其余的springboot与mysql相关的依赖就无需展示

配置文件配置

mybatis-plus:
  global-config:
    db-config:
      #      逻辑删除,删除标志
      logic-delete-value: 1
      #      逻辑删除,未删除标志
      logic-not-delete-value: 0
  type-aliases-package: com.fang.pojo
  configuration:
    #    mybatis-plus日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

2、数据库插入

数据库以此为例

DROP TABLE IF EXISTS sys_user;

CREATE TABLE rbac_plus.sys_user
(
    id INT AUTO_INCREMENT NOT NULL COMMENT '主键ID',
    name VARCHAR(50) NOT NULL COMMENT '名称',
    password VARCHAR(500) NOT NULL COMMENT '密码',
    email VARCHAR(200) NOT NULL  COMMENT '邮箱',
    state INT NOT NULL DEFAULT 0 COMMENT '状态,0为正常,1为异常',
    create_time DATETIME NOT NULL COMMENT '创建时间',
    update_time DATETIME  COMMENT '修改时间',
    deleted INT DEFAULT 0  COMMENT '假删除',
    version INT DEFAULT 1  COMMENT '乐观锁',
    PRIMARY KEY (id)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='user表';

INSERT INTO `rbac_plus`.`sys_user` (`name`, `password`, `email`, `create_time`) VALUES ('一号', '123', '123@qq.com', CURRENT_DATE),
											('二号','234','234.qq.com',CURRENT_DATE),
											('三号','345','345.qq.com',CURRENT_DATE),
											('四号','456','456.qq.com',CURRENT_DATE),
											('五号','567','567.qq.com',CURRENT_DATE),
											('六号','678','678.qq.com',CURRENT_DATE);

3、SpringBoot各个层次的操作

3.1、实体类

/**
 * @author FPH
 * @since 2022.04.27 03点46分
 */
@Data
@TableName("sys_user")
public class SysUser implements Serializable {
    @TableId(type = IdType.AUTO)
    private Integer id;

    private String name;

    private String password;


    private String email;

    private Integer state;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.UPDATE)
    private Date updateTime;

    @TableLogic
    private Integer deleted;

    @Version
    private Integer version;

@TableName指定表名

@TableId指定表的主键,并且定义这是一个自增的主键

@TableField表示填充此属性,

@TableLogic表示假删除

@Version表示乐观锁

以上配置均将在configuration层中实现

3.2、configuration

3.2.1、TableField的insert与update

insert表示插入这一数据时,自动将当前时间填充至此属性

update表示修改此数据时,自动将当前时间填充

这里官网有告诉我们如何配置:

package com.fang.configuration;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @author FPH
 * @since 2022年4月27日04:17:56
 */
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject,"createTime", LocalDateTime.class,LocalDateTime.now());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 起始版本 3.3.0(推荐)
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); 
    }
}

3.2.2、乐观锁配置

官网也有指出如何配置

package com.fang.configuration;

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;

/**
 * @author FPH
 * @since 2022.04.27 03点59分
 */
@Configuration
public class MybatisPlus {
    /**
     * 乐观锁
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

}

3.3、mapper层

package com.fang.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fang.pojo.SysUser;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author FPH
 * @since 2022年4月27日04:04:16
 */
@Repository
public interface SysUserMapper extends BaseMapper<SysUser> {
}

3.4、service层

package com.fang.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.fang.pojo.SysUser;

import java.util.List;

/**
 * @author FPH
 * @since 2022年4月27日04:06:07
 */
public interface SysUserService extends IService<SysUser> {
}

实现类:

package com.fang.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fang.mapper.SysUserMapper;
import com.fang.pojo.SysUser;
import com.fang.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author FPH
 * @since 2022年4月27日04:07:58
 */
@Service("SysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;
}

4、控制层测试

4.1、查询所有

package com.fang.controller;

import com.fang.pojo.SysUser;
import com.fang.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author FPH
 * @since 2022年4月27日04:09:41
 */
@RestController
@RequestMapping("/sysUser")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;
  
    @GetMapping("/baseSelAll")
    public List<SysUser> BaseSelectAll(){
        return sysUserService.list();
    }
}

ApiPost测试,能够成功获取全部的集合

这里可以发现service层无需写这种简单地查询语句,即可实现基本的sql功能

4.2、根据id修改信息

这里能发现有时候乐观锁不能生效,例如以下例子:

package com.fang.controller;

import com.fang.pojo.SysUser;
import com.fang.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author FPH
 * @since 2022年4月27日04:09:41
 */
@RestController
@RequestMapping("/sysUser")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;
   
    @PutMapping("updateById")
    public String updateById(SysUser sysUser){
        return sysUserService.updateById(sysUser)+"";
    }
}

apiPost这样测试:

修改成功,但是去查看日志,发现并没有生效

乐观锁并没有自增


解决方案如下:

新增一个version

此时日志显示这样的信息:

数据库中成功自增

如果此时再修改,但version依旧是传1过去,则修改不成功

version与当前数据库不一致则修改失败

所以我们需要在每次修改时,传入一个version,通过id查询当前version的值,在通过set传入实体类中一起发送到mybatisPlus自带的修改方法中,则能实现乐观锁

4.3、假删除

前面的配置文件指定1表示已经被删除,0表示没被删除

控制层这样写:

package com.fang.controller;

import com.fang.pojo.SysUser;
import com.fang.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

/**
 * @author FPH
 * @since 2022年4月27日04:09:41
 */
@RestController
@RequestMapping("/sysUser")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;
    
    @DeleteMapping("deleteByIds")
    public String deleteById(Integer[] ids){
        return sysUserService.removeByIds(Arrays.asList(ids))+"";
    }
}

通过ids数组批量删除

删除成功

日志sql打印情况如下:

并不是真正地删除数据

插入在下一章记录,此时需要用到数据校验

这篇关于关于SpringBoot整合MyBatis-Plus乐观锁不生效的问题解决方案的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!