mybatis-plus (3.4.2)使用

快速入门

官方文档快速入门案例

配置日志

# 配置日志

mybatis-plus:
  configuration:
    # 配置 mybatis-plus执行的日志类型(可以看到执行过程) 下面是使用了控制台输出 sl4j log4j 等等都可以
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

效果

mybatis-plus (3.4.2)使用_第1张图片

CRUD扩展

数据库中未指定id自增方式 我们可以通过mybatis-plus 来生成
mybatis-plus (3.4.2)使用_第2张图片

插入一条数据

User user = new User();
user.setAge(3);
user.setName("xiuyuan");
user.setEmail("[email protected]");

userMapper.insert(user);

System.out.println(user);

你会发现,我们虽然没有指定id,但是他会自动给我们生成id,并赋给了user
mybatis-plus (3.4.2)使用_第3张图片

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

主键生成策略

分布式系统唯一Id生成方案汇总

Twitter的snowflake(雪花)算法

snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake。

mybatis-plus 默认主键生成方案 ID_WORKER

我们可以通过 @TableId 指定主键生成方式

public class User {
     

    @TableId(type = IdType.ID_WORKER)
    private Long id;
    private String name;
    private Integer age;
    private String email;

IdType

public enum IdType {
     
    AUTO(0), // 数据库id自增
    NONE(1), // 未设置主键
    INPUT(2), //手动输入
    ID_WORKER(3), // 默认的全局唯一id
    UUID(4), // 全局唯一id uuid
    ID_WORKER_STR(5); // ID_WORKER 字符串表示法

    private int key;

    private IdType(int key) {
     
        this.key = key;
    }

    public int getKey() {
     
        return this.key;
    }
}

更新操作

  @Test
    void update(){
     
        User user = new User();
        user.setId(2L);
        user.setAge(20);
		//  自动支持 动态sql(会自动判断 属性是否为''或null)
        int i = userMapper.updateById(user);

    }

mybatis-plus (3.4.2)使用_第4张图片
mybatis-plus (3.4.2)使用_第5张图片
从更新操作中 你会发现它是支持动态sql判断的(填充动态sql)。

自动填充

创建时间和修改时间!这些操作一般都是自动化完成的,我们不希望手动更新!

方式一 数据库级别(工作中不推荐)

mybatis-plus (3.4.2)使用_第6张图片

方式二 代码级别

自动填充功能入门

1、实体类上添加填充注解

// 字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

2、编写一个处理器来处理注解

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

import java.util.Date;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
     


    // 插入时填充的操作
    @Override
    public void insertFill(MetaObject metaObject) {
     
        // 方法签名 MetaObjectHandler 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) {
     
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

测试一下

mybatis-plus (3.4.2)使用_第7张图片

在这里插入图片描述

乐观锁

mybaits-plus乐观锁官方文档

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

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

1、给数据库中增加version字段
mybatis-plus (3.4.2)使用_第8张图片
2、我们的实体类同步字段

// mybatis-plus 的乐观锁 Version注解
@Version
private Integer version;

@Version 说明:

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

3、配置乐观锁插件(新版本已失效)

新版本已失效

@MapperScan("com.zlf.mapper")
@Configuration
public class mybatisPlusConfig {
     

    @Bean
    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor(){
     
        return new OptimisticLockerInnerInterceptor();
    }
}

新版本

@MapperScan("com.zlf.mapper")
@Configuration
public class mybatisPlusConfig {
     

    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
     
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 配置 乐观锁拦截器
        OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
        return interceptor;
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
     
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }
}

测试

/**
     * 测试乐观锁失败(模拟多线程)
     */
    @Test
    void testLock2(){
     
        // 1、查询用户信息
        User user = userMapper.selectById(1L);
        // 2、修改用户信息
        user.setEmail("cccc@abc");
        user.setAge(18);

        User user2 = userMapper.selectById(1L);
        user.setName("小白");
        // 插队修改
        userMapper.updateById(user2);


        userMapper.updateById(user);

    }

mybatis-plus (3.4.2)使用_第9张图片
在这里插入图片描述

查询操作

基础查询

/**
     * 测试查询
     */
    @Test
    void testSelect(){
     
        // 查询一个
        User user = userMapper.selectById(1L);

        // 查询多个  方法签名 List selectBatchIds(@Param("coll") Collection idList);
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1L,2L,3L));

        // 条件查询之一 selectByMap
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","小白"); // key 是列名 value 是要查询的值
        map.put("age",18);  // 多个条件之间是 and
        List<User> users1 = userMapper.selectByMap(map);

    }

分页查询

1、配置分页拦截器

/**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
     

        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 配置 乐观锁拦截器
        OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
        return interceptor;
    }

2、直接使用Page对象

@Test
    void testPage(){
     
        // 参数一:当前页,参数二:显示条数
        Page<User> page = new Page<>(1,5);
        // 分页查询
        Page<User> userPage = userMapper.selectPage(page, null);
        // 获取记录 getRecords()
        userPage.getRecords().forEach(System.out::println);

    }

测试结果
mybatis-plus (3.4.2)使用_第10张图片

删除操作

@Test
    void testDelete(){
     
        // 通过id删除一条记录
        userMapper.deleteById(1L);
        // 通过id集合删除整个集合对应记录
        userMapper.deleteBatchIds(Arrays.asList(2L,3L));

        // 通过条件删除 条件之间为 and
        Map<String, Object> map = new HashMap<>();
        map.put("name","小黑");
        map.put("age",18);
        userMapper.deleteByMap(map);
    }

逻辑删除

逻辑删除官方文档

物理删除:从数据库中直接移除
逻辑删除:在数据库中没有被移除,而是通过一个变量来让他失效!

类似管理员查看被删除的记录。防止数据的丢失,类似于回收站!

1、在数据表中添加一个字段deleted

mybatis-plus (3.4.2)使用_第11张图片

2、在实体类中添加属性

	@TableLogic //逻辑删除注解
    private Integer deleted;

3、配置

mybatis-plus:
  global-config:
    db-config:
      # 配置逻辑删除
      logic-delete-field: deleted  # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略@TableLogic)
      logic-delete-value: 1  # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

测试

    @Test
    void testDelete(){
     
        // 通过id删除一条记录
        userMapper.deleteById(2L);
    }

你会发现 删除变成了更新deleted 的值了
在这里插入图片描述
数据库中
在这里插入图片描述

我们再来查询一下

@Test
    void testLock(){
     
        // 1、查询用户信息
        User user = userMapper.selectById(2L);
        System.out.println(user);

    }

已经查不到了 sql中会过滤 deleted=0 的
mybatis-plus (3.4.2)使用_第12张图片

性能分析插件

旧版本就不说了。
新版本在 执行 SQL 分析打印官方文档

条件构造器

条件构造器官方文档

代码自动生成器

这边使用的版本是3.4.1

<dependency>
   <groupId>com.baomidougroupId>
   <artifactId>mybatis-plus-generatorartifactId>
   <version>3.4.1version>
dependency>

<dependency>
    <groupId>org.apache.velocitygroupId>
    <artifactId>velocity-engine-coreartifactId>
    <version>2.3version>
dependency>

代码生成器官方文档


import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;

@SpringBootTest
class MallApplicationTests {
     

    @Test
    void contextLoads() {
     


    }

    @Test
    public void run() {
     

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("zlf");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setFileOverride(false); //重新生成时文件是否覆盖
        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setIdType(IdType.ID_WORKER); //主键策略
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/数据库名");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("xxxx");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("mall"); //模块名
        pc.setParent("com");
        // com.zlf.edu.controller
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("表名");
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        strategy.setLogicDeleteFieldName("is_deleted");
        // 自动填充配置
        TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
        TableFill gmtModified = new TableFill("gmt_modified",
                FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(gmtCreate);
        tableFills.add(gmtModified);
        strategy.setTableFillList(tableFills);


        mpg.setStrategy(strategy);


        // 6、执行
        mpg.execute();
    }

}

推荐B站Up狂神

良心up主,强烈推荐!!
mybatis-plus (3.4.2)使用_第13张图片

你可能感兴趣的:(java,mybatis)