近来发现对生成框架感兴趣的人好多此处曝光生成框架的编写思路!
我在作品展示分类中提到的基础生成框架是B/S架构的,
并且提供了在线上传模板,生成后整个项目打包下载, 单个文件下载等功能.这些功能这里不做详细说明.可自行添加,
近期我将分享java压缩文件、类似FTP浏览并下载文件的代码。各位可以根据自己的实际情况来选择如何架构,这里我们只讲思路。
在编写生成框架前,你需要做的准备工作如下:
一.设计你要的生成结果
这样说好像有点难以理解, 简单点说,就是一个完整的项目.生成的时候会按照这个项目的模式生成.
二.framemaker框架
framemaker是比较好用的,当然如果你不想用framemaker, 也可以自己写读取模板和替换内容的代码.
准备好上面两步后, 就差不多可以开始编写代码了. 这里我们不考虑界面的美观等.
首先,需要新建一个项目,并且编写一些基础代码。
这里说的基础代码是指JDBC连接数据库,获取表结构及数据库信息等。
当然, 你也可以把数据库连接、模板、项目看成几个单独的模块,在生成工具中提供管理,需要生成时任意组装生成,实现相对比较简单。
然后,就是将基础代码中获取的表结构等信息交给framemaker进行模板替换。
这里提到了模板,您一定在疑惑,模板哪儿来的呢?不要着急,继续向下看。
最后,就是关于生成代码质量最关键的一步了,制作模板。
模板要根据一个成型的项目来编写,这个项目就是准备工作中提到的生成结果。
根据你准备的项目,找到相似的规律,编写模板。
编写模板时,要尽量多的抽取共通,这样会使你的模板编写变的简单容易。
下面简单的说明下如何根据已有项目编写模板:
1.找出项目中的分层规律。比如dao、Service、action、model、vo、common
2.抽取项目中的通用部分,上面的分层中的vo、common两层应该是不会变更的,所以,这两层可以在模板中写死,只需要更改包名即可。
3.逐曾编写模板,比如model的模板:
package ${basepackage}.model;
import javax.validation.constraints.*;
import org.hibernate.validator.constraints.*;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
<#include "/java_imports.include">
public class ${className} extends BaseEntity implements java.io.Serializable {
private static final long serialVersionUID = 5454155825314635342L;
//alias
public static final String TABLE_ALIAS = "${table.tableAlias}";
<#list table.columns as column>
public static final String ALIAS_${column.constantName} = "${column.columnAlias}";
#list>
//date formats
<#list table.columns as column>
<#if column.isDateTimeColumn>
public static final String FORMAT_${column.constantName} = DATE_FORMAT;
#if>
#list>
//columns START
<#list table.columns as column>
/**
* ${column.columnAlias!} db_column: ${column.sqlName}
*/
${column.hibernateValidatorExprssion}
private ${column.javaType} ${column.columnNameLower};
#list>
//columns END
<@generateConstructor className/>
<@generateJavaColumns/>
<@generateJavaOneToMany/>
<@generateJavaManyToOne/>
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
<#list table.columns as column>
.append("${column.columnName}",get${column.columnName}())
#list>
.toString();
}
public int hashCode() {
return new HashCodeBuilder()
<#list table.pkColumns as column>
.append(get${column.columnName}())
#list>
.toHashCode();
}
public boolean equals(Object obj) {
if(obj instanceof ${className} == false) return false;
if(this == obj) return true;
${className} other = (${className})obj;
return new EqualsBuilder()
<#list table.pkColumns as column>
.append(get${column.columnName}(),other.get${column.columnName}())
#list>
.isEquals();
}
}
<#macro generateJavaColumns>
<#list table.columns as column>
<#if column.isDateTimeColumn>
public String get${column.columnName}String() {
return DateConvertUtils.format(get${column.columnName}(), FORMAT_${column.constantName});
}
public void set${column.columnName}String(String value) {
set${column.columnName}(DateConvertUtils.parse(value, FORMAT_${column.constantName},${column.javaType}.class));
}
#if>
public void set${column.columnName}(${column.javaType} value) {
this.${column.columnNameLower} = value;
}
public ${column.javaType} get${column.columnName}() {
return this.${column.columnNameLower};
}
#list>
#macro>
<#macro generateJavaOneToMany>
<#list table.exportedKeys.associatedTables?values as foreignKey>
<#assign fkSqlTable = foreignKey.sqlTable>
<#assign fkTable = fkSqlTable.className>
<#assign fkPojoClass = fkSqlTable.className>
<#assign fkPojoClassVar = fkPojoClass?uncap_first>
private Set ${fkPojoClassVar}s = new HashSet(0);
public void set${fkPojoClass}s(Set<${fkPojoClass}> ${fkPojoClassVar}){
this.${fkPojoClassVar}s = ${fkPojoClassVar};
}
public Set<${fkPojoClass}> get${fkPojoClass}s() {
return ${fkPojoClassVar}s;
}
#list>
#macro>
<#macro generateJavaManyToOne>
<#list table.importedKeys.associatedTables?values as foreignKey>
<#assign fkSqlTable = foreignKey.sqlTable>
<#assign fkTable = fkSqlTable.className>
<#assign fkPojoClass = fkSqlTable.className>
<#assign fkPojoClassVar = fkPojoClass?uncap_first>
private ${fkPojoClass} ${fkPojoClassVar};
public void set${fkPojoClass}(${fkPojoClass} ${fkPojoClassVar}){
this.${fkPojoClassVar} = ${fkPojoClassVar};
}
public ${fkPojoClass} get${fkPojoClass}() {
return ${fkPojoClassVar};
}
#list>
#macro>
当模板逐层编写完毕后,运行你的项目,生成一个瞧瞧吧!
写的不是很详细,有任何问题请及时提出,我会及时修正!