Springboot(十二)——整合mybatis-plus(二)

整合mybatis-plus(二)

插入数据

@Test
public void testInsert(){
    User user = new User();
    user.setName("张三");
    user.setAge(18);
    user.setEmail("963330213@qq.com");

    int result = userMapper.insert(user);//自动帮我们生成id
    System.out.println(result);//受影响的行数
    System.out.println(user);//id自动回填
}

image

数据库插入的id的默认值为:全局唯一id

主键生成策略

官方文档:https://mp.baomidou.com/guide/annotation.html#tablename

雪花算法

SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增的,后面的代码中有详细的注解。

这 64 个 bit 中,其中 1 个 bit 是不用的,然后用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号。

@TableId

  • 描述:主键注解
属性 类型 必须指定 默认值 描述
value String "" 主键字段名
type Enum IdType.NONE 主键类型

IdType

描述
AUTO 数据库ID自增
NONE(默认值) 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUT insert前自行set主键值(手动代码设置)
ASSIGN_ID 分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID 分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)

修改代码重新测试

修改实体类

public class User {

    @TableId(type =IdType.AUTO)//设置主键自增,同时要修改数据库主键自增
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

修改数据库自增
image
输出结果:
image
ID对比,实现自增
image

更新数据

一、编写测试类

@Test
public void testUpdate(){
    User user = new User();
    //通过条件,自动拼接动态sql
    user.setId(6L);
    user.setName("zhangsan");
    //注意:updateById参数不是int类型,而是一个对象
    int i = userMapper.updateById(user);
    System.out.println(i);
}

二、输出结果

image

三、数据库发生改变

image

总结:所有sql语句都是自动拼接的

自动填充

官方文档:https://mp.baomidou.com/guide/auto-fill-metainfo.html
创建时间、修改时间这些操作一般都是自动化完成的,我们不希望手动更新

方式一、数据库级别(工作中不允许修改数据库)

1、在表中新增字段:create_time,update_time
image
2、再次测试插入方法,我们需要先把实体类同步

private Date createTime;
private Date updateTime;

3、查看结果
image
更新时间已修改
image

方式二、代码级别

1、删除数据库的默认值删掉
image
2、实体类字段属性上添加注解

//字段添加填充内容
@TableField(fill = FieldFill.INSERT) //插入的时候实现自动填充
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新的时候实现自动填充
private Date updateTime;

3、编写处理器来处理这个注解

package com.study.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;

@Component
@Slf4j  //日志
public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
    }

    //更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }
}

4、测试插入
image
5、测试更新
image

字段为null解决:https://blog.csdn.net/qq_43647384/article/details/110662507

乐观锁

乐观锁:顾名思义十分乐观,开发中总是认为不会出现问题,无论干什么都不去上锁!,如果出现问题,就再次更新值测试
悲观锁:顾名思义十分悲观,开发中总是认为会出现问题,无论干什么都会上锁!再去操作

乐观锁实现方式:

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

乐观锁:1、先查询,获得版本号 version = 1
--A

update user set name = "zhangsan",version = version + 1
where id = 2 and version = 1

--B 线程抢先完成,这个时候 version = 2,会导致 A 修改失败

update user set name = "zhangsan",version = version + 1
where id = 2 and version = 1

使用Mybatis-plus乐观锁插件

1、给数据库中添加 version 字段
image
image

2、给实体类添加对应的字段

@Version //乐观锁version注解
private Integer version;

3、注册组件

package com.study.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;

@Configuration  //标注这是一个配置类
@MapperScan("com.study.mapper")
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

4、测试乐观锁成功

//测试乐观锁成功!
@Test
public void testMybatisPlusInterceptor(){
    //1、查询用户信息
    User user = userMapper.selectById(1L);
    //2、修改用户信息
    user.setName("zhangsan");
    user.setEmail("963330213@qq.com");
    //3、执行更新操作
    userMapper.updateById(user);
}

image

5、测试乐观锁失败

//测试乐观锁失败
@Test
public void testMybatisPlusInterceptor2(){
    //1、查询用户信息
    User user = userMapper.selectById(1L);
    //2、修改用户信息
    user.setName("zhangsan1");
    user.setEmail("963330213@qq.com");

    //模拟另外一个线程执行了插队操作
    User user2 = userMapper.selectById(1L);
    user2.setName("zhangsan2");
    user2.setEmail("963330213@qq.com");
    userMapper.updateById(user2);

    //自旋锁来尝试多次提交
    userMapper.updateById(user);//如果没有乐观锁就会覆盖插队线程的值!
}

image
查看数据库字段
image

posted @ 2021-07-02 10:47  转身刹那的潇洒  阅读(56)  评论(0编辑  收藏  举报