经验分享-项目基础生成框架的编写

近来发现对生成框架感兴趣的人好多此处曝光生成框架的编写思路!

我在作品展示分类中提到的基础生成框架是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}";
	
	
	//date formats
	<#list table.columns as column>
	<#if column.isDateTimeColumn>
	public static final String FORMAT_${column.constantName} = DATE_FORMAT;
	
	
	
	//columns START
	<#list table.columns as column>
    /**
     * ${column.columnAlias!}       db_column: ${column.sqlName} 
     */ 	
	${column.hibernateValidatorExprssion}
	private ${column.javaType} ${column.columnNameLower};
	
	//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}())
		
			.toString();
	}
	
	public int hashCode() {
		return new HashCodeBuilder()
		<#list table.pkColumns as column>
			.append(get${column.columnName}())
		
			.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}())
			
			.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));
	}
	
			
	public void set${column.columnName}(${column.javaType} value) {
		this.${column.columnNameLower} = value;
	}
	
	public ${column.javaType} get${column.columnName}() {
		return this.${column.columnNameLower};
	}
	


<#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;
	}
	


<#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};
	}
	


当模板逐层编写完毕后,运行你的项目,生成一个瞧瞧吧!

写的不是很详细,有任何问题请及时提出,我会及时修正!

你可能感兴趣的:(经验分享)