欢迎使用开源的代码生成器Code-Builder

4,673 阅读10分钟

背景

本来code-builder是专门为MyBatis Enhance来编写的一块代码生成器,不过仅仅使用到Enhance却没有什么新鲜感,所以把生成这块分离出来提供给大家使用,希望可以对提高项目研发效率提供一些帮助。

code-builder可以用来做什么?

code-builder是一款代码生成maven mojo插件,通过简单的配置就可以完成数据库内Table转换Entity或者其他实体类,想怎么生成完全根据你的个人业务逻辑,code-builder尽可能的完善的提供数据库内的一些定义的信息,让你更方便更灵活的来生成Java文件。

欢迎关注公众号

微信公众号
关注微信公众号,回复加群,获取交流群群号。

源码地址

欢迎去码云进行Issue、喜欢的给我来个Star吧

使用环境

  • Maven构建的项目
  • JDK 1.6以上版本

实现方式

是怎么获取到的数据库信息?

code-builder内部采用了java.sql.ConnectionMetaData元数据的方式来获取数据库内TableColumn等信息,MetaData是不局限于任何的数据库类型的,所以code-builder在基础设计上是可以在任何数据库类型中来完成它的生成任务的,不过初版本仅支持了MySQLMariaDB这两种数据库类型,在code-builder后期更新版本中会把主流的数据库进行添加。

生成模板选型

目前code-builder内部采用了freemarker模板来完成实体类的自动生成,模板由使用者来自定义编写,内部预留了使用其他模板的方式,如果你需要使用别的模板,如:Velocity,对应添加生成的实现业务逻辑即可。

怎么配置?

SpringBoot 方式配置

1.0.3.RELEASE版本添加了集成SpringBootstarter,依赖如下所示:

  • 使用Maven构建工具时,复制下面的内容到pom.xml配置文件内
<dependency>
    <groupId>com.gitee.hengboy</groupId>
    <artifactId>code-builder-spring-boot-starter</artifactId>
    <version>1.0.3.RELEASE</version>
</dependency>
  • 如果你是用的Gradle构建工具,那么复制下面的内容到你的build.gradle
compile group: 'com.gitee.hengboy', name: 'code-builder-spring-boot-starter', version: '1.0.3.RELEASE'

那么我们在application.yml或者application.properties配置文件内该怎么配置相关的参数呢?

hengboy:
  code:
    builder:
      execute: true
      configuration:
        package-prefix: com.code.builder.sample.codebuildersample
        templates:
          -
            name: entity.ftl
            packageName: model
            fileSuffix: Entity
          -
            name: service.ftl
            packageName: service
            fileSuffix: Service
          -
            name: controller.ftl
            packageName: controller
            fileSuffix: Controller
      generator-by-pattern: '%app_user_info%'
      db-type: mysql
      engine-type-enum: freemarker
      builder-dir: classes.templates.builder
      target-dir: generated-sources.java
      tables:
        - app_shop_type
        - app_user_exchange_good
      ignore-class-prefix: App

每个参数的具体介绍请往下看。

Maven Plugin 方式配置

由于code-builderMaven mojo插件的形式创建的,所以我们只需要在项目的pom.xml文件内添加plugin插件配置,如下所示:

<plugin>
    <groupId>com.gitee.hengboy</groupId>
    <artifactId>code-builder-maven-plugin</artifactId>
    <version>1.0.3.RELEASE</version>
    <executions>
        <execution>
            <goals>
                <goal>generator</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
    </dependencies>
    <configuration>
        <execute>true</execute>
        <dbType>MySQL</dbType>
        <dbDriverClassName>com.mysql.jdbc.Driver</dbDriverClassName>
        <dbName>xxxx</dbName>
        <dbUserName>xxxx</dbUserName>
        <dbPassword>xxxxx</dbPassword>
        <dbUrl>jdbc:mysql://xxx.xx.xx.xx:3306</dbUrl>
        <tables>
             <table>app_shop_type</table>
             <table>app_user_exchange_good</table>
         </tables>
         <engineType>FREEMARKER</engineType>
         <generatorByPattern>%app_user_info%</generatorByPattern>
         <ignoreClassPrefix>App</ignoreClassPrefix>
         <builderDir>classes.templates.builder</builderDir>
         <builder>
                <packagePrefix>com.code.builder.sample</packagePrefix>
		         <templates>
		              <template>
		                  <name>entity.ftl</name>
		                  <packageName>model</packageName>
		              </template>
		              <template>
		                  <name>service.ftl</name>
		                  <packageName>service</packageName>
		                  <fileSuffix>Service</fileSuffix>
		              </template>
		              <template>
		                  <name>mapper.ftl</name>
		                  <packageName>mapper</packageName>
		                  <fileSuffix>Mapper</fileSuffix>
		               </template>
		         </templates>
         </builder>
    </configuration>
</plugin>

数据库驱动依赖添加

code-builder不局限你使用的数据库类型,所以在生成时需要使用者添加对应数据类型的依赖,如上面的配置中则是添加了MySQL数据库的依赖

.....
<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>
</dependencies>
.....

仅仅在使用Maven-Plugin形式添加数据驱动依赖

生成的控制开关

并不是每一次的编译或者打包时都需要生成对应的实体,针对这种情况code-builder添加了execute参数来控制开启与关闭。

  • true:开启自动生成
  • false:关闭自动生成

数据库类型配置

执行自动生成前需要配置数据库的相关配置信息

  • dbType:数据库类型,默认使用MySQL数据库类型。
  • dbDriverClassName:数据库驱动类名,根据不用的数据库类型配置不同的驱动类名,默认根据dbType使用内部定义的类名,如需自定义可以设置。(仅maven-plugin使用)

数据库基本信息配置 (仅maven-plugin使用)

  • dbName:数据库名称
  • dbUserName:数据库用户名
  • dbPassword:数据库密码
  • dbUrl:数据库连接路径,连接路径不需要填写数据库名,正确示例如:jdbc:mysql://localhost:3306

生成表名符合规则的表

根据表达式来创建表,表达式与模糊查询语句表达式一般无二,配置generatorByPattern参数并设置对应的表达式就可以根据表达式来匹配出参与生成的Table列表。

  • 指定前缀匹配
<generatorByPattern>app_order%</generatorByPattern>

示例:将会匹配出app_order_infoapp_order_record等表。

  • 指定后缀匹配
<generatorByPattern>%order</generatorByPattern>

示例:将会匹配出app_good_orderapp_exchange_order等表。

  • 包含匹配
<generatorByPattern>%order%</generatorByPattern>

示例:将会匹配出app_order_infoapp_good_order等表。

生成指定表

code-builder支持指定单个或者多个表来生成,只需要配置tables参数即可,如下所示:

<tables>
    <table>app_shop_type</table>
    <table>app_user_exchange_good</table>
</tables>

上面的配置是本次生成仅操作app_shop_typeapp_user_exchange_good两张表。

注意:tables参数的优先级要高于generatorByPattern参数。

自定义builder所需模板路径

code-builder会自动去找classes/templates/builder下的模板,如果使用默认的freemarker模板来生成,那么模板所存放的位置为classes/templates/builder/freemarker。 如果你想自定义模板的路径可以设置builderDir的地址,在这里因为考虑到了不同操作系统的分隔符不一样(Windows系统分隔符\Linux以及O SX分隔符为/)所以这里采用.分隔符配置,code-builder会自动根据操作系统来转换路径,配置如下所示:

<builderDir>classes.code.builder</builderDir>

注意:freemarker文件夹不允许修改,只能修改code-builder加载模板的根路径。

排除生成实体后的前缀

数据库设计有时需要添加前缀,如:app_sys_等,实际生成实体后前缀则是并不想展示,那么配置参数ignoreClassPrefix就可以自动排除前缀,如下所示:

<ignoreClassPrefix>App</ignoreClassPrefix>

注意:由于替换生成后的类名称所以这里要准守驼峰命名规则首字母大写,一次只能配置一个替换前缀。

使用前AppUserInfoEntity,使用后UserInfoEntity

模板配置

使用templates标签配置自定义的模板列表,一次可以使用单个或者多个模板进行生成,如下配置:

<templates>
    <template>
        <name>entity.ftl</name>
        <packageName>entity</packageName>
        <fileSuffix>entity</fileSuffix>
    </template>
    <template>
        <name>service.ftl</name>
        <packageName>service</packageName>
        <fileSuffix>Service</fileSuffix>
    </template>
    <template>
        <name>mapper.ftl</name>
        <packageName>mapper</packageName>
        <fileSuffix>Mapper</fileSuffix>
    </template>
</templates>
  • namefreemarker目录下模板的名称,必填
  • packageName:生成该模板文件后的子包名称,非必填
  • fileSuffix:生成文件的后缀,如:配置后缀为Entity,则添加后缀后的文件名为UserInfoEntity,后缀首字母会自动根据驼峰转换成大写

内置参数

模板驱动数据模型内置了部分参数,code-builder准备的每一个参数都是在生成实体类时都可能会用到的。

Table参数

  • tableName 表名,数据类型:java.lang.String
  • remark 表备注信息,数据类型:java.lang.String
  • entityName 实体类名称,如:user_info转换为userInfo,数据类型:java.lang.String
  • columns 列列表,数据类型:java.util.List<Column>
  • primaryKeys 主键列表,数据类型:java.util.List<Column>
  • hasSqlDate 是否存在java.sql.Date类型,true:存在,false:不存在,数据类型:java.lang.Boolean
  • hasTimeStamp 是否存在java.sql.TimeStamp类型,true:存在,false:不存在,数据类型:java.lang.Boolean
  • hasBigDecimal 是否存在java.math.BigDecimal类型,true:存在,false:不存在,数据类型:java.lang.Boolean
使用方式

freemarker模板${table.xxx},如表名的使用为${table.tableName}

Column参数

  • columnName 列名,如:user_id,数据类型:java.lang.String
  • primaryKey 是否为主键,数据类型:java.lang.Booleantrue:主键,false:非主键
  • foreignKey 是否为外键,数据类型:java.lang.Booleantrue:外键,false:非外键
  • size 列长度,数据类型:java.lang.Integer
  • decimalDigits 小数点精度,数据类型:java.lang.Integer
  • nullable 列是否为空,数据类型:java.lang.Booleantrue:为空,false:非空
  • autoincrement 是否自增,数据类型:java.lang.Booleantrue:自增列,false:普通列
  • defaultValue 默认值,数据类型:java.lang.String
  • remark 列备注,数据类型:java.lang.String
  • jdbcType JDBC类型,对应java.sql.Types内类型,数据类型:java.lang.Integer
  • jdbcTypeName JDBC类型名称,数据类型:java.lang.String
  • javaProperty 格式化后的属性名称,如:userId,数据类型:java.lang.String
  • javaType Java数据类型短名,如:TimeStamp,数据类型:java.lang.String
  • fullJavaType Java数据类型全名,如:java.sql.TimeStamp,数据类型:java.lang.String
使用方式

freemarker模板${column.xxx},如列名的使用为${column.columnName}

基础参数

  • className:Class名称,freemarker指定模板生成文件的类名,模板内配置${className}使用
  • packageName:Package名称,freemarker指定模板生成文件的包名,模板内配置${packageName}使用

怎么自定义模板?

下面提供一个简单的模板示例,根据上面的内置参数可以任意自定义生成文件的内容。

<#if (packageName)??>
package ${packageName};
</#if>
import lombok.Data;

<#if (table.hasSqlDate)>
import java.sql.Date;
</#if>
<#if (table.hasTimeStamp)>
import java.sql.Timestamp;
</#if>
<#if (table.hasBigDecimal)>
import java.math.BigDecimal;
</#if>
/**
 * <p>本类代码由code-builder自动生成</p>
 * <p>表名: ${table.tableName} - ${table.remark}</p>
 * ===============================
 * Created with code-builder.
 * User:恒宇少年
 * Date:${.now}
 * 简书:http://www.jianshTu.com/u/092df3f77bca
 * 码云:https://gitee.com/hengboy
 * ================================
 */
@Data
public class ${className} {
<#list table.primaryKeys as key>
    /**
     * ${key.columnName} - ${key.remark}
     */
    private ${key.javaType} ${key.javaProperty};
</#list>
<#list table.columns as column>
    <#if (!column.primaryKey)>
    /**
     * ${column.columnName} - ${column.remark}
     */
    private ${column.javaType} ${column.javaProperty};
    </#if>
</#list>
}

上面是一个数据实体的freemarker模板内容,把这个模板存放到freemarker目录下,对应在templates标签内添加配置就可以完成数据实体的自动创建,创建后的数据实体内容如下所示:

package com.code.builder.sample.model;
import lombok.Data;

import java.sql.Timestamp;
/**
 * <p>本类代码由code-builder自动生成</p>
 * <p>表名: app_balance_type - 余额类型信息表</p>
 * ===============================
 * Created with code-builder.
 * User:恒宇少年
 * Date:Jul 17, 2018 9:09:13 PM
 * 简书:http://www.jianshTu.com/u/092df3f77bca
 * 码云:https://gitee.com/hengboy
 * ================================
 */
@Data
public class BalanceTypeEntity {
    /**
     * BT_ID - 余额类型主键
     */
    private String btId;
    /**
     * BT_NAME - 余额类型名称
     */
    private String btName;
    /**
     * BT_FLAG - 余额类型标识
     */
    private String btFlag;
    /**
     * BT_CREATE_TIME - 添加时间
     */
    private Timestamp btCreateTime;
    /**
     * BT_MARK - 余额类型备注信息
     */
    private String btMark;
}

创建的实体类去了哪里?

创建的实体类会在target/generated-sources/java目录下,如果你配置packagePrefix参数,会自动在生成目录下创建packagePrefix配置值的子目录。 如:

<packagePrefix>com.code.builder.sample</packagePrefix>

则最终创建的生成根目录为:target/generated-sources/java/com/code/builder/sample

怎么使用?

SpringBoot 方式使用

  1. 运行项目就可以根据配置生成对应的文件

Maven Plugin 方式使用

  1. 执行mvn clean命令用于清空target目录下的内容
  2. 执行mvn compile命令编译项目并且生成实体类

为什么SpringBoot方式不用配置数据库信息?

Maven Plugin方式是通过配置的数据库连接信息以及数据库连接驱动获取数据库连接对象Connection后来操作JDBC元数据

SpringBoot方式则是直接使用项目中配置的DataSource对象实例来进行获取的Connection数据库连接对象后来操作JDBC元数据

注意:如果你是多数据源项目,默认会使用primary数据源实例。