1. 利用freemarker和mybatis进行代码生成
1.1 利用mybatis-gengerator插件为数据库生成
在项目模块依赖中导入插件以及数据库连接依赖
<!-- mybatis generator 自动生成代码插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
<configurationFile>src/main/resources/generator-config-business.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
</dependencies>
</plugin>
在为XXX数据库生成文件时,直接修改configurationFile中的参数即可,改换xml文件。XML文件的定义如下所示
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="Mysql" targetRuntime="MyBatis3" defaultModelType="flat">
<!-- 自动检查关键字,为关键字增加反引号 -->
<property name="autoDelimitKeywords" value="true"/>
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!--覆盖生成XML文件-->
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
<!-- 生成的实体类添加toString()方法 -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<!-- 不生成注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- 配置数据源,需要根据自己的项目修改 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="XXX"
userId="XXX"
password="XXX">
</jdbcConnection>
<!-- domain类的位置 targetProject是相对pom.xml的路径-->
<javaModelGenerator targetProject="../business/src/main/java"
targetPackage="com.monster.business.domain"/>
<!-- mapper xml的位置 targetProject是相对pom.xml的路径 -->
<sqlMapGenerator targetProject="../business/src/main/resources"
targetPackage="mapper"/>
<!-- mapper类的位置 targetProject是相对pom.xml的路径 -->
<javaClientGenerator targetProject="../business/src/main/java"
targetPackage="com.monster.business.mapper"
type="XMLMAPPER"/>
<!-- 需要为多少个表生成,则依次填写即可-->
<table tableName="station" domainObjectName="Station"/>
</context></generatorConfiguration>
此时部署已经完成,找到Maven中该模块的插件,找到mybatis-generator,启动即可,如下图所示:
1.2 利用freemarker快速生成增删改查以及Vue文件
首先需要编写模块文件即ftl文件,例子如下所示:,其中的${module}由代码生成类进行注入
package com.monster.${module}.req;
import com.monster.common.req.PageReq;
public class ${Domain}QueryReq extends PageReq {
@Override
public String toString() {
return "${Domain}QueryReq{" +
"} " + super.toString();
}
}
在有了模板之后,需要进行模板读取,以及根据模板生成文件,定义为FreemarkerUtil类
package com.monster.train.generator.util;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
public class FreemarkerUtil {
//ftl文件所在位置
static String ftlPath = "generator/src/main/java/com/monster/train/generator/ftl/";
static Template temp;
/**
* 读模板
*/
public static void initConfig(String ftlName) throws IOException {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
cfg.setDirectoryForTemplateLoading(new File(ftlPath));
cfg.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_31));
temp = cfg.getTemplate(ftlName);
}
/**
* 根据模板,生成文件
*/
public static void generator(String fileName, Map<String, Object> map) throws IOException, TemplateException {
FileWriter fw = new FileWriter(fileName);
BufferedWriter bw = new BufferedWriter(fw);
temp.process(map, bw);
bw.flush();
fw.close();
}
}
由于针对数据库的表进行模板生成文件,会进行数据库连接的操作,再定义一个DBUtil类(不再展示,可以私信博主获取)
针对数据库表中属性,会有不同的类型,由此再定义一个Field类,来声明所有的属性类型
至此,编写代码生成器类,如下所示:
package com.monster.train.generator.gen;
import com.monster.train.generator.util.Field;
import com.monster.train.generator.util.FreemarkerUtil;
import com.monster.train.generator.util.DbUtil;
import freemarker.template.TemplateException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class ServerGenerator {
static boolean readOnly = false;
static String vuePath = "admin/src/views/main/";
static String serverPath = "[module]/src/main/java/com/monster/[module]/";
static String pomPath = "generator/pom.xml";
//为哪个模块生成代码,则修改
static String module = "XXX";
static {
new File(serverPath).mkdirs();
}
public static void main(String[] args) throws Exception {
// 获取mybatis-generator
String generatorPath = getGeneratorPath();
// 比如generator-config-member.xml,得到module = member
module = generatorPath.replace("src/main/resources/generator-config-", "").replace(".xml", "");
System.out.println("module: " + module);
serverPath = serverPath.replace("[module]", module);
// new File(servicePath).mkdirs();
System.out.println("servicePath: " + serverPath);
// 读取table节点
Document document = new SAXReader().read("generator/" + generatorPath);
Node table = document.selectSingleNode("//table");
System.out.println(table);
Node tableName = table.selectSingleNode("@tableName");
Node domainObjectName = table.selectSingleNode("@domainObjectName");
System.out.println(tableName.getText() + "/" + domainObjectName.getText());
// 为DbUtil设置数据源
Node connectionURL = document.selectSingleNode("//@connectionURL");
Node userId = document.selectSingleNode("//@userId");
Node password = document.selectSingleNode("//@password");
System.out.println("url: " + connectionURL.getText());
System.out.println("user: " + userId.getText());
System.out.println("password: " + password.getText());
DbUtil.url = connectionURL.getText();
DbUtil.user = userId.getText();
DbUtil.password = password.getText();
// 示例:表名 monster_test // Domain = monsterTest String Domain = domainObjectName.getText();
// domain = monsterTest
String domain = Domain.substring(0, 1).toLowerCase() + Domain.substring(1);
// do_main = monster-test
String do_main = tableName.getText().replaceAll("_", "-");
// 表中文名
String tableNameCn = DbUtil.getTableComment(tableName.getText());
List<Field> fieldList = DbUtil.getColumnByTableName(tableName.getText());
Set<String> typeSet = getJavaTypes(fieldList);
// 组装参数
Map<String, Object> param = new HashMap<>();
param.put("module", module);
param.put("Domain", Domain);
param.put("domain", domain);
param.put("do_main", do_main);
param.put("tableNameCn", tableNameCn);
param.put("fieldList", fieldList);
param.put("typeSet", typeSet);
param.put("readOnly", readOnly);
System.out.println("组装参数:" + param);
gen(Domain, param, "service", "service");
gen(Domain, param, "controller/admin", "adminController");
gen(Domain, param, "req", "saveReq");
gen(Domain, param, "req", "queryReq");
gen(Domain, param, "resp", "queryResp");
}
private static void gen(String Domain, Map<String, Object> param, String packageName, String target) throws IOException, TemplateException {
FreemarkerUtil.initConfig(target + ".ftl");
String toPath = serverPath + packageName + "/";
new File(toPath).mkdirs();
String Target = target.substring(0, 1).toUpperCase() + target.substring(1);
String fileName = toPath + Domain + Target + ".java";
System.out.println("开始生成:" + fileName);
FreemarkerUtil.generator(fileName, param);
}
private static void genVue(String do_main, Map<String, Object> param) throws IOException, TemplateException {
FreemarkerUtil.initConfig("vue.ftl");
new File(vuePath + module).mkdirs();
String fileName = vuePath + module + "/" + do_main + ".vue";
System.out.println("开始生成:" + fileName);
FreemarkerUtil.generator(fileName, param);
}
private static String getGeneratorPath() throws DocumentException {
SAXReader saxReader = new SAXReader();
Map<String, String> map = new HashMap<String, String>();
map.put("pom", "http://maven.apache.org/POM/4.0.0");
saxReader.getDocumentFactory().setXPathNamespaceURIs(map);
Document document = saxReader.read(pomPath);
Node node = document.selectSingleNode("//pom:configurationFile");
System.out.println(node.getText());
return node.getText();
}
/**
* 获取所有的Java类型,使用Set去重
*/
private static Set<String> getJavaTypes(List<Field> fieldList) {
Set<String> set = new HashSet<>();
for (int i = 0; i < fieldList.size(); i++) {
Field field = fieldList.get(i);
set.add(field.getJavaType());
}
return set;
}
}
该生成器类会与generator-config-XXX.xml进行相关联,获取其中的参数,点击运行之后为其中声明的表生成相应的增删改查类。