石一歌的MybatisPlus笔记

MybatisPlus(3.0.5)

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

CRUD

基础的crud拓展很简单,不再赘述

  • public interface UserMapper extends BaseMapper<User>
    
  • public class UserService extends ServiceImpl<UserMapper, User>
    
  • 在继承的mybatisplus不能满足需求时,在相应的类进行手动实现

主键生成策略

有关各种主键生成策略的优劣对比

默认的主键策略是雪花算法,一般无需修改。由于mysql的索引是B+树,可以修改为主键自增来提高性能。在单机系统此两种方案都没有问题,但分布式系统需要使用考虑诸如uuid之类的方法。

  • 实体设置主键自增(数据库需要配置主键自增)

    	@TableId(type = IdType.AUTO)
        private Long id;
    
  • 全局设置主键自增

    #全局设置主键生成策略
    mybatis-plus.global-config.db-config.id-type=auto
    
  • 源码

    public enum IdType {
        AUTO(0),//数据库ID自增  
        NONE(1),//该类型为未设置主键类型   
        //该类型可以通过自己注册自动填充插件进行填充
        INPUT(2),//用户输入ID
    	//以下3种类型、只有当插入对象ID 为空,才自动填充。     
        ID_WORKER(3),//全局唯一ID (idWorker)      
        UUID(4),//全局唯一ID (UUID)          
        ID_WORKER_STR(5);//字符串全局唯一ID (idWorker 的字符串表示)    
    }
    
  • 新版本

    合并了雪花算法的全局唯一主键,支持多种类型

    public enum IdType {
        AUTO(0),
        NONE(1),
        INPUT(2),
        ASSIGN_ID(3),//只有当用户未输入时,采用雪花算法生成一个适用于分布式环境的全局唯一主键,类型可以是String和number;
        ASSIGN_UUID(4);
    }
    

自动填充

阿里巴巴开发手册要求,数据库表必须有gmt_creategmt_modified字段,且自动化

  • 数据库实现(不建议使用)

    • 数据库新增字段gmt_creategmt_modified,类型为datetime,设置默认值CURRENT_TIMESTAMPgmt_modified设置随时间戳更新。
  • 代码实现

    • 新增字段不变,去除默认值和更新。

    • 添加如下注解

      @TableField(fill= FieldFill.INSERT)
      private Date createTime;
      @TableField(fill= FieldFill.INSERT_UPDATE)
      private Date updateTime;
      
    • 实现MetaObjectHandler

      @Component
      @Slf4j
      public class MyMetaObjectHandler implements MetaObjectHandler {
          @Override
          public void insertFill(MetaObject metaObject) {
              log.info("insert...");
              this.setFieldValByName("gmtCreate", new Date(), metaObject);
              this.setFieldValByName("gmtUpdate", new Date(), metaObject);
          }
      
          @Override
          public void updateFill(MetaObject metaObject) {
              log.info("update...");
              this.setFieldValByName("gmtUpdate", new Date(), metaObject);
          }
      }
      
    • 新版本(修改user中相应属性类型为LocalDateTime)

      this.strictInsertFill(metaObject, "gmtCreate", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
      // 或者
      this.strictInsertFill(metaObject, "gmtCreate", () -> LocalDateTime.now(), LocalDateTime.class);
      

乐观锁插件

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

  • 乐观锁注解

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

    @Configuration
    @MapperScan("按需修改")
    public class MybatisPlusConfig {
        @Bean
        public OptimisticLockerInterceptor optimisticLockerInterceptor() {
            return new OptimisticLockerInterceptor();
        }
    
    }
    
  • 新版本

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

分页插件

  • 配置

    @Configuration
    @MapperScan("com.baomidou.cloud.service.*.mapper*")
    public class MybatisPlusConfig {
        @Bean
        public PaginationInterceptor paginationInterceptor() {
            PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
            paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
            return paginationInterceptor;
        }
    }
    
  • 新版本

    	@Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
            return interceptor;
        }
    
  • 使用

    Page<User> page = new Page<>(2,5);
    userMapper.selectPage(page,null);
    page.getRecords().forEach(System.out::println);
    

逻辑删除

  • 数据库新增字段deleted,默认值0

  • 逻辑删除注解

    @TableLogic
    private Integer deleted;
    
  • 配置

    @Bean
    public ISqlInjector sqlInjector(){
        return new LogicSqlInjector();
    }
    
    mybatis-plus:
      global-config:
        db-config:
          logic-delete-value: 1
          logic-not-delete-value: 0
    
  • 新版本(无需注解和注入bean)

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

性能分析插件

  • 配置

    	@Bean
        @Profile({"dev", "test"})// 设置 dev test 环境开启,保证我们的效率
        public PerformanceInterceptor performanceInterceptor() {
            PerformanceInterceptor interceptor = new PerformanceInterceptor();
            interceptor.setMaxTime(1);// 设置sql执行的最大时间,如果超过了则不执行
            interceptor.setFormat(true);// 是否格式化代码
            return interceptor;
        }
    
  • 新版本已移除,建议使用p6spy

条件构造器

代码生成器

  • 配置

    public class KuangCode {
    public static void main(String[] args) {
        // 需要构建一个 代码自动生成器 对象 
        AutoGenerator mpg = new AutoGenerator(); 
        
        // 配置策略 
        // 1、全局配置 
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir"); 
        gc.setOutputDir(projectPath+"/src/main/java");
        gc.setAuthor("狂神说"); gc.setOpen(false);
        gc.setFileOverride(false);
        
        // 是否覆盖
        gc.setServiceName("%sService");
        
        // 去Service的I前缀
        gc.setIdType(IdType.ID_WORKER);
        gc.setDateType(DateType.ONLY_DATE);
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);
        
        //2、设置数据源
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/kuang_community? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        dsc.setDbType(DbType.MYSQL); mpg.setDataSource(dsc);
        
        //3、包的配置
        PackageConfig pc = new PackageConfig();
        //只需要改实体类名字 和包名 还有 数据库配置即可
        pc.setModuleName("blog"); pc.setParent("com.kuang");
        pc.setEntity("entity"); pc.setMapper("mapper");
        pc.setService("service"); pc.setController("controller");
        mpg.setPackageInfo(pc);
        
        //4、策略配置
        StrategyConfig strategy = new StrategyConfig();
      strategy.setInclude("blog_tags","course","links","sys_settings","user_record"," user_say");
        
        // 设置要映射的表名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        
        // 自动lombok;
        strategy.setLogicDeleteFieldName("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);
        
        // 乐观锁
        strategy.setVersionFieldName("version");
        strategy.setRestControllerStyle(true);
        strategy.setControllerMappingHyphenStyle(true);
        
        // localhost:8080/hello_id_2 
        mpg.setStrategy(strategy);
        mpg.execute(); //执行 
    	}
    }
    
  • 新版本

    • pom

      <dependency>
          <groupId>com.baomidou</groupId>
          <artifactId>mybatis-plus-generator</artifactId>
          <version>3.5.1</version>
      </dependency>
      
    • 使用

      FastAutoGenerator.create(DATA_SOURCE_CONFIG)
          // 全局配置
          .globalConfig((scanner, builder) -> builder.author(scanner.apply("请输入作者名称?")).fileOverride())
          // 包配置
          .packageConfig((scanner, builder) -> builder.parent(scanner.apply("请输入包名?")))
          // 策略配置
          .strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
                              .controllerBuilder().enableRestStyle().enableHyphenStyle()
                              .entityBuilder().enableLombok().addTableFills(
                                      new Column("create_time", FieldFill.INSERT)
                              ).build())
          /*
              模板引擎配置,默认 Velocity 可选模板引擎 Beetl 或 Freemarker
             .templateEngine(new BeetlTemplateEngine())
             .templateEngine(new FreemarkerTemplateEngine())
           */
          .execute();
      
      
      // 处理 all 情况
      protected static List<String> getTables(String tables) {
          return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
      }
      
    • 配置参考官方文档

posted @ 2022-01-08 23:36  Faetbwac  阅读(78)  评论(0编辑  收藏  举报