根据数据库表的元数据生成支持Rest、RPC协议的工程服务(标准化的代码分层结构工程)。 加速新工程的建设。
生成代码的结构依赖于模板的定义。本工程中定义分为三个工程
${projectName}-domain-api:接口层 - RPC接口API工程
${projectName}-domain:领域层 - RPC接口实现(包含domain层 + 基础设施层)
${projectName}-application:应用层 - Rest接口实现
应用层,实现领域间协作、任务编排、Rest服务等。其包结构规范如下:
领域服务的API接口,包括DTO、领域服务接口等。其包结构规范如下:
领域服务的实现层,包括领域对象、领域服务及持久化层的具体实现。其包结构规范如下:
我们使用的是rapid-framework框架生成项目,pom中的引入如下:
com.googlecode.rapid-framework
rapid-generator
4.0.6
项目生成依赖于模板文件,新建template文件夹放置模板,同时包含以下几个文件
生成项目时的配置信息,放入Resource文件夹中
<properties>
<comment>
代码生成器配置文件:
1.会为所有的property生成property_dir属性,如pkg=com.company => pkg_dir=com/company
2.可以引用环境变量: ${env.JAVA_HOME} or System.properties: ${user.home},property之间也可以相互引用
comment>
<entry key="basepackage">com.nameentry>
<entry key="namespace">pagesentry>
<entry key="outRoot">/Users/entry>
<entry key="tableRemovePrefixes">t_entry>
<entry key="jdbc_username">usernameentry>
<entry key="jdbc_password">passwordentry>
<entry key="jdbc_url">jdbc:mysql://XXXentry>
<entry key="jdbc_driver">com.mysql.jdbc.Driverentry>
<entry key="java_typemapping.java.sql.Timestamp">java.util.Dateentry>
<entry key="java_typemapping.java.sql.Date">java.util.Dateentry>
<entry key="java_typemapping.java.sql.Time">java.util.Dateentry>
<entry key="java_typemapping.java.lang.Byte">Integerentry>
<entry key="java_typemapping.java.lang.Short">Integerentry>
<entry key="java_typemapping.java.math.BigDecimal">Longentry>
properties>
生成的项目基本信息
projectName=demoapp-test
groupName=com.group
versionName=1.0.0-SNAPSHOT
### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
public class CodeGenerator {
public static void main(String[] args) throws Exception {
// 模板地址,默认为项目根目录
String templatePath = "template";
GeneratorFacade g = new GeneratorFacade();
Customizer customizer = new Customizer(g.getGenerator().getOutRootDir());
//选择配置文件风格
customizer.determineCfgStyle();
g.getGenerator().addTemplateRootDir(templatePath);
// 删除生成器的输出目录
//g.deleteOutRootDir();
// 通过数据库表生成文件
g.generateByTable("t_student");
customizer.processCfgStyle();
System.out.println("代码生成完毕");
// g.generateByTable("t_student","t_location");
// 自动搜索数据库中的所有表并生成文件,template为模板的根目录
// g.generateByAllTable();
// 按table名字删除文件
// g.deleteByTable("table_name", "template");
}
}
我们的需求中,不同的项目组成员可能使用不同风格的配置文件,有的用.properties,有的用yaml。因此在生成时,两种风格的配置文件同时生成,在根据其选择,递归地删除不需要的文件。
public class Customizer {
/**
* outPath:输出目录
*/
private String outPath;
/**
* deleteStyle: 需要被删除的风格文件类型
*/
private String deleteStyle;
public Customizer(String outPath) {
this.outPath = outPath;
}
/**
* @Description 提示支持的配置文件风格并从控制台选择
**/
public void determineCfgStyle(){
System.out.println("配置文件风格选择:yaml风格输入1,properties风格输入2");
Scanner sc = new Scanner(System.in);
int cfgStyle = sc.nextInt();
if (cfgStyle==1){
this.deleteStyle = "properties";
}else {
this.deleteStyle = "yml";
}
}
/**
* @Description 根据选择的风格删除冗余的配置文件
**/
public void processCfgStyle(){
File file = new File(outPath);
delete(file,deleteStyle);
}
private void delete(File f, String includeName)
{
File[] fi=f.listFiles();
if (null!=fi) {
//遍历文件和文件夹
for (File file : fi) {
//如果是文件夹,递归查找
if (file.isDirectory()) {
delete(file, includeName);
} else if (file.isFile()) {
String filename = file.getName();
if (filename.endsWith(includeName)) {
file.delete();
}
}
}
}
}
}
我们尝试将代码生成器打为jar包,并可配置个性化数据。但是可配置的文件已经写死在Resource文件夹内。
想出的第一种解决方法是,根据输入,动态修改配置文件,但打包成jar之后,jar内的文件无法修改,放弃;第二种方法是希望从外部读取指定的配置文件,但是使用的源码从classpath中直接读取,已经写死。
最终使用第二种方法实现。解决方法是:命令行运行时,指定classpass的扫描路径,指令为-Xbootclasspath/a:[当前文件夹的绝对路径]
将release文件夹内的所有文件,放置于本地的一个文件夹内。命令行运行如下命令:
java -Xbootclasspath/a:./ -jar scc-rapid-generator.jar
再选择配置文件风格后即可生成代码