• MybatisPlus


    MybatisPlus

    MybatisPlus概述

    需要基础:Spring,SpringMVC,Mybatis。

    学习MybatisPlus的原因:

    MybatisPlus可以节省我们大量工作时间,所有的CRUD代码它都可以自动完成!

    简介

    MybatisPlus是什么?Mybatis本来是简化JDBC操作的

    官网:https://baomidou.com/ MybatisPlus,简化Mybatis

     

     

    特性

    • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑

    • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作,BaseMapper

    • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求,以后简单的CRUD操作,它不用自己编写了。

    • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错

    • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题

    • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作

    • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )

    • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用

    • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询

    • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库

    • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询

    • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

    快速入门

    地址:https://baomidou.com/guide/quick-start.html#%E5%88%9D%E5%A7%8B%E5%8C%96%E5%B7%A5%E7%A8%8B

    使用第三方组件:

    1. 导入相应的依赖

    2. 研究依赖如何配置

    3. 代码如何编写

    4. 提高扩展技术能力

    步骤:

    1. 创建数据库 mybatis_plus

    2. 创建user表

       DROP TABLE IF EXISTS user;
       ​
       CREATE TABLE user
       (
        id BIGINT(20) NOT NULL COMMENT '主键ID',
        name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
        age INT(11) NULL DEFAULT NULL COMMENT '年龄',
        email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
        PRIMARY KEY (id)
       );
       --真是开发中,version(乐观锁),delete(逻辑删除),gmt_create,gmt_modified
    3. 编写项目,初始化项目,使用SpringBoot初始化

    4. 导入依赖

               <!--数据库驱动-->
               <dependency>
                   <groupId>mysql</groupId>
                   <artifactId>mysql-connector-java</artifactId>
               </dependency>
              <!--lombok       -->
               <dependency>
                   <groupId>org.projectlombok</groupId>
                   <artifactId>lombok</artifactId>
               </dependency>
               <!--mybatis-plus-->
               <!--mybatis-plus是自己开发的,并非官方的       -->
               <dependency>
                   <groupId>com.baomidou</groupId>
                   <artifactId>mybatis-plus-boot-starter</artifactId>
                   <version>3.0.5</version>
               </dependency>

      说明:我们使用mybatis-plus可以节省我们大量代码,尽量不要同时导入mybatis和mybatis-plus。版本差异

    5. 连接数据库!这一步和mybatis相同!

       #mysql 5 驱动不同 com.mysql.jdbc.Driver
       #spring.datasource.data-username=root
       #spring.datasource.data-password=123456
       #spring.datasource.driver-class-name=com.mysql.jdbc.Driver
       #spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8
       ​
       ​
       #mysql 8 驱动不同 com.mysql.cj.jdbc.Driver,需要增加时区的配置 serverTimezone=GMT%2B8
       spring.datasource.data-username=root
       spring.datasource.data-password=123456
       spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
       spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    6. 传统方式:pojo-dao(连接mybatis,配置mapper.xml文件)-service-controller

    1. 使用mybatis-plus之后

      • pojo

         @Data
         @AllArgsConstructor
         @NoArgsConstructor
         public class User {
             private Long id;
             private String name;
             private Integer age;
             private String email;
         }
      • mapper接口

         // 在对应的Mapper上面继承基本的接口 BaseMapper
         @Repository  // 代表持久层
         public interface UserMapper extends BaseMapper<User> {
             // 所有的CRUD操作都已经编写完成了
             // 你不需要像以前一样配置一大堆文件了
         }
      • 注意点:我们需要在主启动类下去扫描我们mapper包下的所有接口

         // 扫描我们的 mapper 文件夹
         @MapperScan("com.zhou.mapper")
         @SpringBootApplication
         public class MybatisplusApplication {
         ​
             public static void main(String[] args) {
                 SpringApplication.run(MybatisplusApplication.class, args);
            }
         }
      • 测试类中测试

         @SpringBootTest
         class MybatisplusApplicationTests {
         ​
             // 继承了BaseMapper,所有的方法都来自自己父类
             // 我们也可以编写自己的扩展方法
             @Autowired
             private UserMapper userMapper;
             @Test
             void contextLoads() {
                 // 参数是一个Wrapper,条件构造器
                 // 查询全部用户
                 List<User> users = userMapper.selectList(null);
                 for (User user : users) {
                     System.out.println(user);
                }
            }
         }
      • 测试的结果

      • 文件目录结构

         

    思考问题:

    1. SQL谁帮我们写的?Mybatis-plus

    2. 方法哪里来的?Mybatis-plus都写好了,只需使用

    配置日志

    我们所有的SQL是不可见的,我们希望知道它是如何执行的,所以我们必须要看日志

     #配置日志
     mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

    配置完毕日志之后,后面的学习需要注意这个自动生成SQL,你们会喜欢Mybatis-plus

    CRUD扩展

    insert

     // 插入测试
         @Test
         public void testInsert(){
             User user = new User();
             user.setName("雅典娜");
             user.setAge(18);
             user.setEmail("12345686");
     ​
             int result = userMapper.insert(user); //帮我们自动生成id
             System.out.println(result);  //受影响的行数
             System.out.println(user);    //发现,id会自动生成
       

     

     

     

     

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

    主键生成策略

    默认ID_WORKER全局唯一id

    分布式系统唯一id生成:https://www.cnblogs.com/haoxinyue/p/5208136.html

    雪花算法

    snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。可以保证几乎全球唯一。

    主键自增

    我们需要配置主键自增:

    1. 实体类字段上

        public class User {
       ​
           // 对应数据库中的主键 (uuid,自增id,雪花算法,redis,zookeeper)
           @TableId(type= IdType.AUTO)
           private Long id;
           private String name;
           private Integer age;
           private String email;
       }
    2. 数据库字段一定要是自增的

    1. 再次测试插入即可

    2. 其余源码解释

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

       

       

    UPDATE

      //测试更新
         @Test
         public void testUpate(){
             // 通过条件动态拼接SQL
             User user = new User();
             user.setId(5l);
             user.setName("卡拉卡拉");
             // 注意:updateById 但是参数是一个对象!
             int i = userMapper.updateById(user);
             System.out.println(i);
        }

    所有的SQL都是自动帮你动态配置的。

     

    自动填充

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

    阿里巴巴开发手册:所有的数据表:gmt_create,gmt_modified几乎所有的表都要配置上,而且需要自动化

    方式一:数据库级别

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

    1. 再次测试插入方法,先同步User类属性。

           private Date createTime;
           private Date updateTime;
    2. 再次更新查看结果

     

    方式二:代码级别

    1. 删除数据库的默认值,更新操作

    2. 实体类字段默认值需要增加注解

           // 字段填充内容
           @TableField(fill= FieldFill.INSERT)
           private Date createTime;
       ​
           //
           @TableField(fill=FieldFill.INSERT_UPDATE)
           private Date updateTime;
    3. 编写处理器来处理这个注解即可

       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;
       import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;
       ​
       @Slf4j
       @Component   //一定不要忘记把处理器加到IOC容器中
       public class MyMetaObjectHandler implements MetaObjectHandler {
           // 插入时的填充策略
           @Override
           public void insertFill(MetaObject metaObject) {
               log.println("start insert fill ....");
               this.setFieldValByName("createTime",new Date(),metaObject);
               this.setFieldValByName("updateTime",new Date(),metaObject);
          }
           // 更新时的填充策略
           @Override
           public void updateFill(MetaObject metaObject) {
               log.println("start update fill ....");
               this.setFieldValByName("updateTime",new Date(),metaObject);
          }
       }
    4. 测试插入

    5. 测试更新,观察时间即可。

    乐观锁

    在面试过程中,我们会经常被问到乐观锁,悲观锁。这个其实很简单。

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

    悲观锁:顾名思义十分悲观,他总是人实总是出现问题,无论干什么都会上锁,再去操作。

    我们这里主要讲解 乐观锁机制

    乐观锁实现方式:

    • 取出记录时,获取当前version

    • 更新时,带上这个version

    • 执行更新时, set version = newVersion where version = oldVersion

    • 如果version不对,就更新失败

     乐观锁 1.先查询,获得版本号 version=1
     --A
     update user set name="kakka",version=version+1
     where id=2 and version=1
     ​
     --B 线程抢先完成,这个时候version=2 会导致A修改失败
     update user set name="dfa" ,version=version+1
     where id=2 and version =1

    测试乐观锁的插件

    1. 先给数据库中增加version字段!version默认值为1

    2. 我们实体类同步

           @Version //乐观锁注解
           private Integer version;
    3. 注册组件

       // 扫描我们的 mapper 文件夹
       @MapperScan("com.zhou.mapper")
       @EnableTransactionManagement
       @Configuration  //配置类
       public class MyBatisPlusConfig {
       ​
           @Bean
           public OptimisticLockerInterceptor optimisticLockerInterceptor() {
               return new OptimisticLockerInterceptor();
          }
       }
    4. 测试

       //测试乐观锁失败! 多线程下
           @Test
           public void testOptimisticLocker2(){
               User user = userMapper.selectById(1l);
               user.setName("ool1111");
               user.setAge(5);
       ​
               // 模拟另外一个线程执行了插队操作
               User user2 = userMapper.selectById(1l);
               user2.setName("ool1111");
               user2.setAge(6);
               userMapper.updateById(user2);
       ​
               // 自旋锁尝试多次提交
               userMapper.updateById(user);// 如果没有了乐观锁就会覆盖了这个值
          }

     

    查询操作

     // 测试查询
         @Test
         public void testSelectById(){
             User user = userMapper.selectById(1l);
             System.out.println("user = " + user);
        }
     ​
         // 测试批量查询
         @Test
         public void testSelectByBatchId(){
             List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
             users.forEach(System.out::println);
        }
     ​
         // 条件查询 map
         @Test
         public void testSelectByBatchIds(){
             HashMap<String,Object> map = new HashMap<>();
             // 自定义查询
             map.put("name","ool");
             List<User> users = userMapper.selectByMap(map);
             users.forEach(System.out::println);
        }

    分页查询

    分页在网站使用的十分之多!

    1. 原始的limit进行分页

    2. pageHelper第三方插件

    3. MP也实现了分页插件的内置

    使用内置插件

    1. 配置拦截器组件即可

       @Bean
           public PaginationInterceptor paginationInterceptor() {
               PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
               // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
               // paginationInterceptor.setOverflow(false);
               // 设置最大单页限制数量,默认 500 条,-1 不受限制
               // paginationInterceptor.setLimit(500);
               // 开启 count 的 join 优化,只针对部分 left join
               paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
               return paginationInterceptor;
          }
    2. 直接使用Page对象即可!

           // 测试分页插件
           @Test
           public void testPage(){
               // 使用分页插件后,所有的分页操作也变得简单了
               // 参数一:当前页 参数二:页面大小
               Page<User> page = new Page<>(2, 5);
               userMapper.selectPage(page,null);
               page.getRecords().forEach(System.out::println);
          }

    删除操作

    1. 根据id删除记录

       // 测试删除
           @Test
           public void testDeleteById(){
               userMapper.deleteById(1l);
          }
       ​
           // 通过id批量删除
           @Test
           public void testDeleteBacthId(){
               userMapper.deleteBatchIds(Arrays.asList(1296275246239977474l,1296275246239977476l));
          }
       ​
           // 通过map删除
           @Test
           public void testDeleteMap(){
               HashMap<String, Object> map = new HashMap<>();
               map.put("name","雅典娜");
               userMapper.deleteByMap(map);
          }

      我们在工作中遇到一些问题:逻辑删除

     

    逻辑删除

    物理删除:在数据库中直接移除

    逻辑删除:在数据库中没有被移除,而是通过一个变量来让它失效!deleted=0=>deleted=1

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

    测试一下:

    1. 在数据表中增加一个deleted字段

    1. 实体类中增加属性

           @TableLogic   // 逻辑删除
           private Integer deleted;
    2. 配置

       // 逻辑删除
       @Bean
       public ISqlInjector sqlInjector(){
           return new LogicSqlInjector();
       }
       #配置逻辑删除
       mybatis-plus.global-config.db-config.logic-delete-value=1
       mybatis-plus.global-config-db-config.logic-not-delete-value=0
    3. 测试删除

    记录依旧在数据库中,但是值已经变化了

    以上的CRUD及其扩展操作,我们都必须精通。会大大提高工作效率。

     

    性能分析插件

    我们在平时的开发中,会遇到一些慢SQL。测试!druid

    作用:性能分析拦截器,用于输出每条SQL语句及其执行时间

    MP也提供性能分析插件,如果超过这个时间就停止运行!

    1. 导入插件

       // SQL执行效率插件
       @Bean
       @Profile({"dev","test"})  // 设置dev test 环境开启 保证效率
       public PerformanceInterceptor performanceInterceptor(){
           PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
           // 在工作中,不允许用户等待
           performanceInterceptor.setMaxTime(100); // ms 设置SQL执行的最大时间,如果超过了则不执行
           performanceInterceptor.setFormat(true); // 是否格式化代码
           return performanceInterceptor;
       }

      记住,要在SoringBoot中配置环境为dev或者test环境

    1. 测试使用

       @Test
       void contextLoads() {
           // 参数是一个Wrapper,条件构造器
           // 查询全部用户
           List<User> users = userMapper.selectList(null);
           for (User user : users) {
               System.out.println(user);
          }
       }

    使用性能分析插件,可以帮助我们提高效率

    条件构造器Wrapper

    十分重要:wrapper

    我们写一些十分复杂的SQL就可以使用它来替代

     

    1. 测试一:

       @Test
       void contextLoads() {
       ​
           // 查询name不为空,并且邮箱不为空的用户,年龄大于等于12
           QueryWrapper<User> wrapper = new QueryWrapper<>();
           wrapper.isNotNull("name")
              .isNotNull("email")
              .ge("age",12);
           userMapper.selectList(wrapper).forEach(System.out::println);    // 和我们刚才学习的map对比一下
       }

     

    代码生成器

    dao,pojo,service,controller都给我自动生成

    AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

     

     // 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
     public class CodeGenerator {
     ​
         /**
          * <p>
          * 读取控制台内容
          * </p>
          */
         public static String scanner(String tip) {
             Scanner scanner = new Scanner(System.in);
             StringBuilder help = new StringBuilder();
             help.append("请输入" + tip + ":");
             System.out.println(help.toString());
             if (scanner.hasNext()) {
                 String ipt = scanner.next();
                 if (StringUtils.isNotEmpty(ipt)) {
                     return ipt;
                }
            }
             throw new MybatisPlusException("请输入正确的" + tip + "!");
        }
     ​
         public static void main(String[] args) {
             // 代码生成器
             AutoGenerator mpg = new AutoGenerator();
     ​
             // 全局配置
             GlobalConfig gc = new GlobalConfig();
             String projectPath = System.getProperty("user.dir");
             gc.setOutputDir(projectPath + "/src/main/java");
             gc.setAuthor("jobob");
             gc.setOpen(false);
             // gc.setSwagger2(true); 实体属性 Swagger2 注解
             mpg.setGlobalConfig(gc);
     ​
             // 数据源配置
             DataSourceConfig dsc = new DataSourceConfig();
             dsc.setUrl("jdbc:mysql://localhost:3306/ant?useUnicode=true&useSSL=false&characterEncoding=utf8");
             // dsc.setSchemaName("public");
             dsc.setDriverName("com.mysql.jdbc.Driver");
             dsc.setUsername("root");
             dsc.setPassword("密码");
             mpg.setDataSource(dsc);
     ​
             // 包配置
             PackageConfig pc = new PackageConfig();
             pc.setModuleName(scanner("模块名"));
             pc.setParent("com.baomidou.ant");
             mpg.setPackageInfo(pc);
     ​
             // 自定义配置
             InjectionConfig cfg = new InjectionConfig() {
                 @Override
                 public void initMap() {
                     // to do nothing
                }
            };
     ​
             // 如果模板引擎是 freemarker
             String templatePath = "/templates/mapper.xml.ftl";
             // 如果模板引擎是 velocity
             // String templatePath = "/templates/mapper.xml.vm";
     ​
             // 自定义输出配置
             List<FileOutConfig> focList = new ArrayList<>();
             // 自定义配置会被优先输出
             focList.add(new FileOutConfig(templatePath) {
                 @Override
                 public String outputFile(TableInfo tableInfo) {
                     // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                     return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
                             + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
                }
            });
             /*
             cfg.setFileCreate(new IFileCreate() {
                 @Override
                 public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                     // 判断自定义文件夹是否需要创建
                     checkDir("调用默认方法创建的目录,自定义目录用");
                     if (fileType == FileType.MAPPER) {
                         // 已经生成 mapper 文件判断存在,不想重新生成返回 false
                         return !new File(filePath).exists();
                     }
                     // 允许生成模板文件
                     return true;
                 }
             });
             */
             cfg.setFileOutConfigList(focList);
             mpg.setCfg(cfg);
     ​
             // 配置模板
             TemplateConfig templateConfig = new TemplateConfig();
     ​
             // 配置自定义输出模板
             //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
             // templateConfig.setEntity("templates/entity2.java");
             // templateConfig.setService();
             // templateConfig.setController();
     ​
             templateConfig.setXml(null);
             mpg.setTemplate(templateConfig);
     ​
             // 策略配置
             StrategyConfig strategy = new StrategyConfig();
             strategy.setNaming(NamingStrategy.underline_to_camel);
             strategy.setColumnNaming(NamingStrategy.underline_to_camel);
             strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
             strategy.setEntityLombokModel(true);
             strategy.setRestControllerStyle(true);
             // 公共父类
             strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
             // 写于父类中的公共字段
             strategy.setSuperEntityColumns("id");
             strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
             strategy.setControllerMappingHyphenStyle(true);
             strategy.setTablePrefix(pc.getModuleName() + "_");
             mpg.setStrategy(strategy);
             mpg.setTemplateEngine(new FreemarkerTemplateEngine());
             mpg.execute();
        }
     }
    1. 添加代码生成器依赖

       <dependency>
           <groupId>com.baomidou</groupId>
           <artifactId>mybatis-plus-generator</artifactId>
           <version>3.3.2</version>
       </dependency>
    1. 添加 模板引擎 依赖

      MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎。

      Velocity(默认):

       <dependency>
           <groupId>org.apache.velocity</groupId>
           <artifactId>velocity-engine-core</artifactId>
           <version>2.2</version>
       </dependency>

      Freemarker:

       <dependency>
           <groupId>org.freemarker</groupId>
           <artifactId>freemarker</artifactId>
           <version>2.3.30</version>
       </dependency>

      Beetl:

       <dependency>
           <groupId>com.ibeetl</groupId>
           <artifactId>beetl</artifactId>
           <version>3.1.8.RELEASE</version>
       </dependency>

      注意!如果您选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。

       AutoGenerator generator = new AutoGenerator();
       ​
       // set freemarker engine
       generator.setTemplateEngine(new FreemarkerTemplateEngine());
       ​
       // set beetl engine
       generator.setTemplateEngine(new BeetlTemplateEngine());
       ​
       // set custom engine (reference class is your custom engine class)
       generator.setTemplateEngine(new CustomTemplateEngine());
       ​
       // other config
       ...

     

    • 编写配置

    MyBatis-Plus 的代码生成器提供了大量的自定义参数供用户选择,能够满足绝大部分人的使用需求。

    • 配置 GlobalConfig

       GlobalConfig globalConfig = new GlobalConfig();
       globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
       globalConfig.setAuthor("jobob");
       globalConfig.setOpen(false);
    • 配置 DataSourceConfig

       DataSourceConfig dataSourceConfig = new DataSourceConfig();
       dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/ant?useUnicode=true&useSSL=false&characterEncoding=utf8");
       dataSourceConfig.setDriverName("com.mysql.jdbc.Driver");
       dataSourceConfig.setUsername("root");
       dataSourceConfig.setPassword("password");
    • 自定义模板引擎

    请继承类 com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine

    • 自定义代码模板

     //指定自定义模板路径, 位置:/resources/templates/entity2.java.ftl(或者是.vm)
     //注意不要带上.ftl(或者是.vm), 会根据使用的模板引擎自动识别
     TemplateConfig templateConfig = new TemplateConfig()
        .setEntity("templates/entity2.java");
     ​
     AutoGenerator mpg = new AutoGenerator();
     //配置自定义模板
     mpg.setTemplate(templateConfig);
    • 自定义属性注入

     InjectionConfig injectionConfig = new InjectionConfig() {
         //自定义属性注入:abc
         //在.ftl(或者是.vm)模板中,通过${cfg.abc}获取属性
         @Override
         public void initMap() {
             Map<String, Object> map = new HashMap<>();
             map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
             this.setMap(map);
        }
     };
     AutoGenerator mpg = new AutoGenerator();
     //配置自定义属性注入
     mpg.setCfg(injectionConfig);
     entity2.java.ftl
     自定义属性注入abc=${cfg.abc}
     ​
     entity2.java.vm
     自定义属性注入abc=$!{cfg.abc}
    • 字段其他信息查询注入

    relationship

     new DataSourceConfig().setDbQuery(new MySqlQuery() {
     ​
         /**
          * 重写父类预留查询自定义字段<br>
          * 这里查询的 SQL 对应父类 tableFieldsSql 的查询字段,默认不能满足你的需求请重写它<br>
          * 模板中调用: table.fields 获取所有字段信息,
          * 然后循环字段获取 field.customMap 从 MAP 中获取注入字段如下 NULL 或者 PRIVILEGES
          */
         @Override
         public String[] fieldCustom() {
             return new String[]{"NULL", "PRIVILEGES"};
        }
     })

     

  • 相关阅读:
    SQL(二)语法
    SQL(一)简介
    linux学习(六)文件基本属性
    Linux学习(五)远程登录
    Linux学习(四) 忘记密码解决方法
    怎样理解阻塞非阻塞与同步异步的区别?
    Python的lambda匿名函数
    Twisted源码分析系列01-reactor
    Python装饰器学习(九步入门)
    Python关键字yield的解释
  • 原文地址:https://www.cnblogs.com/Athena-life/p/13535899.html
Copyright © 2020-2023  润新知