一、引言

在项目开发中,我们有碰到大量的简单、重复的增删改查需求,通过阅读若依框架https://github.com/yangzongzhuan/RuoYi 的代码生成器实现,结合我项目所用的技术栈,开发出本项目的代码生成器。

二、Velocity 简单介绍

1、Velocity是一个基于Java的模板引擎,我们可以往Context容器中填值,在vm文件中使用模板语言(Velocity Template Language)获取变量的值,生成一套通用的模板代码。

2、引入依赖:

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


        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>2.0</version>
        </dependency>

3、语法示例:

获取Context中的ClassName值:${ClassName}

判断:#if($table.crud || $table.sub)     

遍历:#foreach ($column in $columns)

结束:#end

/**
 * ${functionName}对象 ${tableName}
 * 
 * @author ${author}
 * @date ${datetime}
 */
#if($table.crud || $table.sub)
#set($Entity="BaseEntity")
#elseif($table.tree)
#set($Entity="TreeEntity")
#end
@Data
public class ${ClassName} extends BasicEntity
{
    private static final long serialVersionUID = 1L;

#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
    /** $column.columnComment */
#if($column.list)
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#if($parentheseIndex != -1)
    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
#elseif($column.javaType == 'Date')
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
#else
    @Excel(name = "${comment}")
#end
#end
    private $column.javaType $column.javaField;

#end
#end
#if($table.sub)
    /** $table.subTable.functionName信息 */
    private List<${subClassName}> ${subclassName}List;

#end

}

三、若依代码生成器核心源码阅读

前置:根据业务代码和模板语言编写代码模板

1、获取数据库表列表,查询 information_schema.tables 表

select table_name, table_comment, create_time, update_time
from information_schema.tables
where table_schema = (select database())

2、初始化表结构信息,填充代码生成器基本信息,插入到 gen_table表

public static void initTable(GenTable genTable, String operName)
{
        genTable.setClassName(convertClassName(genTable.getTableName()));
        genTable.setPackageName(GenConfig.getPackageName());
        genTable.setModuleName(getModuleName(GenConfig.getPackageName()));
        genTable.setBusinessName(getBusinessName(genTable.getTableName()));
        genTable.setFunctionName(replaceText(genTable.getTableComment()));
        genTable.setFunctionAuthor(GenConfig.getAuthor());
        genTable.setCreateBy(operName);
}

3、初始化表的列信息:查询 information_schema.`COLUMNS`表,插入到 gen_table_column表

select table_name, column_name, column_type, data_type, column_comment, column_key
from information_schema.`COLUMNS`
where table_schema = 'smart_ca' and table_name = '表名'

4、初始化vm,加载模板

 public static void initVelocity()
    {
        Properties p = new Properties();
        try {
            // 加载classpath目录下的vm文件
            p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
            // 定义字符集
            p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8);
            // 初始化Velocity引擎,指定配置Properties
            Velocity.init(p);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

5、给容器Context中设置模板变量(重要),例:

        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("tplCategory", genTable.getTplCategory());
        velocityContext.put("tableName", genTable.getTableName());
        velocityContext.put("ClassName", genTable.getClassName());
        velocityContext.put("moduleName", genTable.getModuleName());

6、设置模板

        List<String> templates = new ArrayList<String>();
        templates.add("vm/java/domain.java.vm");
        templates.add("vm/java/mapper.java.vm");
        templates.add("vm/java/service.java.vm");
        templates.add("vm/java/serviceImpl.java.vm");
        templates.add("vm/java/controller.java.vm");

7、渲染模板,生成至指定位置

// 渲染模板
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(template, Constants.UTF8);
tpl.merge(context, sw);
String path = getGenPath(table, template);
FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8);

四、结合项目业务开发代码生成器

1、梳理项目通用代码(重要)

和团队成员一同梳理出通用的代码,我们是要一键生成前后端代码,直接实现增删改查。模板代码必须是经过前后端同学一起验证,避免反复修改。

2、结合自己的业务,定义所有需要的变量,并且使用velocity模板语法,使用变量替换代码。

3、编写操作后台,将模板中需要用到的变量,存储到gen_table,gen_table_column表,以便整个流程使用。

4、开发者点击代码生成时,查询gen_table, gen_table_column表中的数据,设置模板变量到容器Context中,这边要注意把之前自定义的变量全部 put

5、设置代码生成路径,我们的代码默认生成在项目根路径的 generator目录。

Logo

快速构建 Web 应用程序

更多推荐