实现并开源了一个有意思的命令行代码生成器
一直想有一个直接在命令行就可以生成代码的工具,之前一直在用Mybatis Generator插件,但是这个是收费的,并且我想更改模版不是很方便,并且通过gui来操作没有直接使用命令行方便。
我理想中的代码生成器,可以很方便的在项目工作目录里生成代码,并且可以适应不同的项目,在不同的项目里生成不同的样板代码。
正好最近工作中有一个报表任务,针对不同的业务做报表,这种场景写的代码非常样板式,于是我自己实现了一个,并且开源了。
github仓库地址:
https://github.com/aidonggua/code-generator
cg设计理念
.cg工作目录
我参考了git的思路,在每个项目里生成一个目录作为cg的工作目录
可以通过cg init 命令在你的项目中创建这个.cg目录。
cg init 命令会默认生成一些常用模版,可以根据每一个项目的具体情况来修改模版
任务链
每一张表通常会生成好几个文件,并且文件之间的信息可能会互相依赖,所以我设计了一个任务链,后执行的任务可以读取先执行任务的信息
通过config.yaml文件可以配置任务链,并且每一个任务都可以配置独有的属性
mysql:
username: root
password: 123456
host: 127.0.0.1
port: 3306
database: test
table: user
author: yehao
base-package: com.example
module: test
tasks:
# 生成java实体
- name: JavaEntity
template: java_entity.tpl
output: .cg/output
file-postfix: .java
variables:
sub-package: dao.domain
enable: true
# 生成java mapper类
- name: JavaMapper
template: java_mapper.tpl
output: .cg/output
file-postfix: Mapper.java
variables:
sub-package: dao.mapper
class-postfix: Mapper
enable: true
# 生成java mybatis 的xml文件
- name: JavaMapperXml
template: java_mapper_xml.tpl
output: .cg/output
file-postfix: Mapper.xml
enable: true
模版引擎
调研了一些常用模版引擎,我最终发现还是go自带的模版引擎用起来最优雅,我最喜欢下面几个 特性:
通过减号-可以控制空行,这样模版文件就不会看起来非常紧凑难以阅读
命令之间还可以通过|管道符来嵌套使用,可以讲几个简单的命令组成一个复杂的命令
可以很好的控制空行和支持调用函数(可以把这个特性作为模版里的命令功能)
我还把取值方式全部改成了命令的方式{{命令 参数}},并增加了一些自定义命令,例如字符串转换操作、日期、类型转换等等。
还提供了读取配置文件和获取表信息等命令(这是最核心的),例如{{config 配置名}}、{{table "comment"}}
{{refs 任务 配置名}}命令还可以读取其他任务里的配置信息
示例1:🌰
package {{config "base-package"}}.{{config "module"}}.{{var "sub-package"}};
{{""}}
{{- range imports}}
{{.}}
{{end -}}
import com.baomidou.mybatisplus.annotation.tableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
/**
* {{table "name"}}
*
* @Author {{config "author"}}
* @Date {{now}}
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@TableName("{{table "name"}}")
@ApiModel(value="{{table "comment"}}实体类", description="{{table "name"}}")
public class {{table "name" | camelCase | title}} {
{{- range columns}}
@ApiModelProperty(value = "{{.comment}}")
@TableField("{{.name}}")
private {{dbToJava .type}} {{camelCase .name}}{{";"}}
{{end -}}
}
示例2:🌰
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="{{config "base-package"}}.{{config "module"}}.{{refs "JavaMapper" "sub-package"}}.{{table "name" | camelCase | title}}{{refs "JavaMapper" "class-postfix"}}">
<resultMap id="BaseResultMap" type="{{config "base-package"}}.{{config "module"}}.{{refs "JavaEntity" "sub-package"}}.{{table "name" | camelCase | title}}">
{{range columns -}}
{{" "}}<id column="{{.name}}" jdbcType="{{dbToJDBC .type}}" property="{{camelCase .name}}" />
{{end -}}
</resultMap>
<sql id="Base_Column_List">
{{" " -}}
{{range $i,$v := columns -}}
{{if ne $i 0}},{{end}}{{.name -}}
{{end}}
</sql>
</mapper>