mybatis-plus代码生成器

526 阅读4分钟

关于代码生成器,目的是为了生成项目基本骨架,基本都是对各种构造器(Builder)的构建。包括

  • DataSourceConfig.Builder 数据库相关配置

  • GlobalConfig.Builder

    全局配置,包括作者、是否开启Swagger、生成文件目录等

  • PackageConfig.Builder

    包配置,选择父包名、模块名、实体\mapper\service等包名、mapper.xml输出路径。

  • TemplateConfig.Builder

    模板配置,自由选择禁用\启用哪些模块(默认全部启用)

  • InjectionConfig.Builder

    注入配置,比如说生成木块记录日志,可以启用这个。

  • StrategyConfig.Builder
    策略配置,需要生成代码对应表名、entuty\mapper\service....策略配置

  • templateEngine
    需要选择的模板引擎。


代码(静态)

首先创建一个SpringBoot的项目,为了方便后期拓展创建了一个父工程,统一管理公共包。

依赖
<properties>
    <java.version>1.8</java.version>
    <springboot.version>2.6.6</springboot.version>
    <spring-boot-starter-web.version>2.6.6</spring-boot-starter-web.version>
    <spring-boot-starter-test.version>2.6.6</spring-boot-starter-test.version>
    <spring-boot-starter-freemarker.version>2.6.6</spring-boot-starter-freemarker.version>
    <mysql.version>8.0.28</mysql.version>
    <druid.version>1.2.8</druid.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <lombok.version>1.18.12</lombok.version>
    <mybatis-plus.spring.boot.version>3.5.1</mybatis-plus.spring.boot.version>
    <mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version>
    <swagger.version>1.6.5</swagger.version>
    <log4j.version>1.2.17</log4j.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>${springboot.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring-boot-starter-web.version}</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>${spring-boot-starter-test.version}</version>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
        <optional>true</optional>
    </dependency>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
    </dependency>
<!-- 这里使用druid相关配置需要用到log4j -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>${druid.version}</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>${log4j.version}</version>
    </dependency>

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>${mybatis-plus.spring.boot.version}</version>
    </dependency>

    <!--      代码生成依赖  -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>${mybatis-plus-generator.version}</version>
    </dependency>

   <!-- 模板引擎 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
        <version>${spring-boot-starter-freemarker.version}</version>
    </dependency>

    <!-- swagger api生成 -->
    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-annotations</artifactId>
        <version>${swagger.version}</version>
    </dependency>

</dependencies>
配置
spring:
  datasource:
    name: myBlog
    url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      initialSize: 1
      minIdle: 1
      maxActive: 20
      maxWait: 60000
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      validationQuery: select 'x'
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: false
      maxOpenPreparedStatements: 20
      #开启StatFilter
      filter:
        stat:
          enabled: true
          log-slow-sql: true
          slow-sql-millis: 1000
        #开启Slf4jFilter
        slf4j:
          enabled: true
          data-source-log-enabled: false
          connection-log-enabled: false
          statement-log-enabled: false
          result-set-log-enabled: false
        #开启WallFilter
        wall:
          enabled: true
          log-violation: true
          throw-exception: false
          config:
            delete-where-none-check: true
      #开启Web
      web-stat-filter:
        enabled: true
        exclusions: /druid/*,*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico
        url-pattern: /*
      stat-view-servlet:
        enabled: true
        login-username: admin
        login-password: 123456
#mybatisplus 日志配置
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
#    cache-enabled: true
  global-config:
    db-config:
      #logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  mapper-locations: mapper/*.xml
  type-aliases-package: com.roily.entity
  type-handlers-package: com.roily.typeHandler
  type-enums-package: com.roily.enums

具体看注释,有些用不到,比如druid的相关。

生成器

数据库相关枚举类,也可以写一个properties,用Property解析读取。

@Getter
public enum DbProperties {

    URL("url", "jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&charactEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8"),
    USER("user", "root"),
    PASSWORD("pass", "123456");
    private String property;
    private String value;
    DbProperties(String prop, String value) {
        this.property = prop;
        this.value = value;
    }
}

数据库配置也可以写一个properties,放在静态代码块执行。
配置放在public,能读取到就行。 image.png

class CodeMake {
    static {
        InputStream in = ClassLoader.getSystemResourceAsStream("public/db.properties");
        Properties prop = new Properties();
        try {
            prop.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(prop);
    }
}

代码生成器(静态)

class CodeMake {
    public static void main(String[] args) {

        DataSourceConfig.Builder dataSourceConfigBuilder =
                new DataSourceConfig.Builder(
                        DbProperties.URL.getValue(),
                        DbProperties.USER.getValue(),
                        DbProperties.PASSWORD.getValue());
        //配置 entity service xml impl 等文件输出路径
        Map<OutputFile, String> outputFileStringMap =
                Collections.singletonMap(OutputFile.xml, "mp-01\src\main\resources\mapper");
                
        FastAutoGenerator
                .create(dataSourceConfigBuilder)
                //.create(DbProperties.URL.getValue(),DbProperties.PASSWORD.getValue(),DbProperties.USER.getValue())
                .globalConfig(builder -> {
                    builder.author("roilyFish") // 设置作者
                            .dateType(DateType.TIME_PACK)//实体日期属性类型
                            .commentDate("yyyy-MM-dd")
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .disableOpenDir()//生成文件后、不要打开目录
                            .outputDir("mp-01\src\main\java"); // 指定输出目录
                })
                //包路径配置
                .packageConfig(builder -> {
                    builder
                            .parent("com.roily.mp01") // 设置父包名 会影响package
                            .moduleName("backstage") // 设置父包模块名
                            .entity("entity")//实体类包名
                            .service("service")//service包名
                            .serviceImpl("service.impl")//impl包名
                            .mapper("mapper")//mapper接口包名
                            .controller("controller")//controller包名
                            .other("other")
                            //.xml("mp-01\src\main\resources\mapper")//mapper.xml 输出路径
                            //以上配置都基于父包路径
                            .pathInfo(outputFileStringMap); // 设置mapperXml生成路径
                })
                //模板配置
                .templateConfig(builder -> {
                    builder
                            //.disable()//禁用所有模板
                            //.disable(TemplateType.ENTITY)//禁用模板  不生成Entity
                            .entity("/templates/entity.java")
                            //.service("/templates/service.java")
                            //.serviceImpl("/templates/serviceImpl.java")
                            //.mapper("/templates/mapper.java")
                            ////.mapperXml("/templates/mapper.xml")
                            //.controller("/templates/controller.java")
                            .build();
                })
                .injectionConfig(builder -> {
                    builder
                            .beforeOutputFile((tableInfo, objectMap) -> {
                                    System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
                                    System.out.println(objectMap);
                                }

                            )
                            .customMap(Collections.singletonMap("test", "baomidou"))
                            //.customFile(Collections.singletonMap("test.txt", "/templates/entity.vm"))
                            .build();
                })
                .strategyConfig(builder -> {
                    builder.addInclude("user")// 设置需要生成的表名
                            .addTablePrefix("t_", "c_") // 设置过滤表前缀
                            .addTableSuffix("_info")// 设置过滤表后缀
                            //.addFieldPrefix("") // 设置过滤字段前缀
                            //.addFieldSuffix("") // 设置过滤字段后缀
                            .entityBuilder()
                                //.disableSerialVersionUID()//禁用生成serialVersionUID
                                .enableLombok()//允许启用lombok  没有get set  简洁
                                .enableRemoveIsPrefix()//允许去除bollean类型is前缀
                                .enableTableFieldAnnotation()// 开启生成实体时,生成字段注解 即 @TableField
                                .enableActiveRecord()//ActiveRecord 模式 crud更简洁
                                //.versionColumnName("version")//设置乐观锁字段
                                .versionPropertyName("version")//设置乐观锁属性
                                //.logicDeleteColumnName("deleted")//逻辑删除字段
                                .logicDeletePropertyName("deleted")//逻辑删除属性
                                .naming(NamingStrategy.underline_to_camel)//数据库名  驼峰命名
                                .columnNaming(NamingStrategy.underline_to_camel)//数据库字段 驼峰命名
                                //.addSuperEntityColumns("id")
                                //.addIgnoreColumns("deleted")//忽略字段
                                .addTableFills(new Column("create_time", FieldFill.INSERT), new Column("update_time", FieldFill.INSERT_UPDATE))
                                .idType(IdType.AUTO)//主键生成策略
                                .fileOverride()//覆盖已有文件
                                //.formatFileName("%s")
                            .build()
                                .controllerBuilder()
                                //.superClass(BaseController.class)//设置父类
                                .enableRestStyle()//@RestController
                                //.formatFileName("%sAction")//格式化文件名称
                            .build()

                            .serviceBuilder()
                                //.superServiceClass()//父类
                                .formatServiceFileName("%sService")
                                .formatServiceImplFileName("%sServiceImpl")
                            .build()

                            .mapperBuilder()
                                //.superClass()//父类
                                //.enableMapperAnnotation()//开启@Mapper 一般都会的配置扫描包
                                .enableBaseResultMap()
                                //.formatMapperFileName("%sMapper")
                                //.formatXmlFileName("%sMapper")
                            .build();
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();

    }
}

其实静态的有了,动态交互的应该也可以出来。