首页
学习
活动
专区
圈层
工具
发布

mybatisplus相关特性使用

1.日志配置

我们所有的sql现在是不可见的,我们希望知道它是怎么执行的,所以我们必须要看日志! 配置如下 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

如图所示,有查询语句以及具体参数,返回值也有的

2.mybatis自带的雪花算法生成id

我们可以测试一下mybatisplus的插入,我们发现在插入的时候如果不指定id,会根据雪花算法自动生成一个id并且待会id到我们的传入实体里。

删除刚刚的记录我们再次重试一次,但是这里我们设置主键是自增id,发现其仍然采用的是雪花算法生成id

那如果我们想让其自动生成的主键是自增主键怎么办呢? 1,数据库里对该字段设置为自增型 2,对应的实体里字段type修改为自增

代码语言:javascript
复制
@TableId(type = IdType.AUTO)
    private Long id;

测试结果,这里id都很大主要因为我们之前插入了比较大的id导致后即使把数据删了也不能从头开始,可以用`alter table table_name AUTO_INCREMENT=n`指定自增字段值从哪开始

我们看下其idwork可以指定哪些类型

代码语言:javascript
复制
public enum IdType {
AUTO(0), // 数据库id自增
NONE(1), // 库中未设置主键
INPUT(2), // 手动输入
ID_WORKER(3), // 默认的全局唯一id
UUID(4), // 全局唯一id uuid
ID_WORKER_STR(5); //ID_WORKER 字符串表示法
}
注意:如果我们指定了某种id生成类型,别的类型操作就没有用了,如这里设置其为自增型,那么就算我们手动设置了id的值,其最终插入的id也是自动的哟,必须使用input才可以手动数据

3.对于更新操作,mybatisplus有个自动拼接sql(动态sql)

以前单纯的mybatis我们可能要在xml里写sql根据某个字段是否有值然后去判断是否要拼接这个字段的sql,可以测试下;

根据主键进行三个字段的更新

只根据一个字段的更新

4.自动填充

创建时间、修改时间!这些个操作一遍都是自动化完成的,我们不希望手动更新! 阿里巴巴开发手册:所有的数据库表:gmt_create、gmt_modified几乎所有的表都要配置上!而且需要自动化,实现方式主要有以下两种!

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

1、在表中新增字段 create_time, update_time

方式二:代码级别
  • 1、删除数据库的默认值、更新操作!
  • 2.实体类字段属性上需要增加注解
代码语言:javascript
复制
// 字段属性设置 ----TableField表中属性所用的注解--区别于id专用注解
//设置其为自动填充,填充策略为插入时自动填充内容 
@TableField(fill = FieldFill.INSERT)
private Date createTime;
//设置插入和更新时候都自动填充注解
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
  • 3、编写处理器来处理这个注解 这里MetaObjectHandler为参数处理,我们可以定义自己的处理方式,可以定义自己的策略

如下代码中,我们定义了设置了对加了插入填充注解的字段以及设置了更新填充注解的字段进行扫描,并且对各个字段设置自己的填充策略。

代码语言:javascript
复制
package com.future.test.easycodetest.controller;

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;

@Slf4j
@Component // 一定不要忘记把处理器加到IOC容器中!
public class MyMetaObjectHandler implements MetaObjectHandler {
    // 插入时的填充策略,根据字段名填空,如果字段名相匹配则进行填充
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill.....");
// setFieldValByName(String fieldName, Object fieldVal, MetaObject  metaObject
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
    // 更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill.....");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

注意:我们第三步做的是全局处理,如果字段设置了自动填充,且我们为该字段设置了自动填充策略才会进行填充,比如我们虽然在步骤3里设置了插入和更新操作时候都对update_time自动填充一个值,但是我们在步骤2如果不进行设置填充策略的话,那就扫描不到不会自动更新。

5,乐观锁

乐观锁需要两步骤

1.配置插件

spring xml方式:

spring boot注解方式:

代码语言:javascript
复制
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}

上面是官方的配置,我之前因为分页插件已经引入了一个配置了,这次就也写在里面了,其实这里可以上上面的配置里再加一个乐观锁拦截器到mp拦截器里,这里为了区分,我又定义了一个bean

#2.在实体类的字段上加上@Version注解

代码语言:javascript
复制
@Version
private Integer version;

说明:

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity
  • 仅支持 updateById(id)update(entity, wrapper) 方法
  • update(entity, wrapper) 方法下, wrapper 不能复用!!!

测试一下发现真的可以,mp自动给我加了version条件以及自动升级了version得值

这里模拟下多线程修改的问题,发现user2并没有更新,这是因为user1 user2拿到的值都是2,但是user1线更新把值置为了3,user2比较更新的时候就失败了,如果我们想让user2也更新成功那么就必须就cas和自旋重新取值更新了

下一篇
举报
领券