RT,前段时间让做一个自动生成的DEMO,然,网上的不明甚以,故摘此篇,部分内容来自互联网,算是一个大的总结。
这个demo实现的是在web页面输入表名列来自动生成一些常用基本的类。
TemplateUtil 类
获取模板文件的信息,并对生成的java文件的命名及存放路径进行处理
注:basicAction类是action基类,是读取现有文件并做一定出来实现自动生成更改。
private String project = null;// 项目名
List fileName = new ArrayList();// 模板文件名
private String tempPath = null;// 模板文件存放路径
public TemplateUtil(String url) {
setProject(url);
setTempPath(url);
setFileName();
}
public void setProject(String url) {
project=url;
}
public void setTempPath(String tempPath) {
this.tempPath = tempPath + "/src/template";
}
public String getTempPath() {
return tempPath;
}
public List getFileName() {
return fileName;
}
public void setFileName() {
File filePath = new File(tempPath);
if (filePath.isDirectory()) {
File[] files = filePath.listFiles();
for (File file : files) {
fileName.add(file.getName());
}
}
}
public String getProject() {
return project;
}
public String getSavePath(String type, String project, String className) {
String newJavaFile = null;
if (type.equalsIgnoreCase("dao")) {
newJavaFile = project + "/src/dao/" + className
+ "Dao.java";
} else if (type.equalsIgnoreCase("daoImpl")) {
newJavaFile = project + "/src/dao/impl/" + className
+ "DaoImpl.java";
} else if (type.equalsIgnoreCase("service")) {
newJavaFile = project + "/src/service/" + className
+ "Service.java";
} else if (type.equalsIgnoreCase("serviceImpl")) {
newJavaFile = project + "/src/service/impl/"
+ className + "ServiceImpl.java";
} else if (type.equalsIgnoreCase("entity")) {
newJavaFile = project + "/src/model/"
+ className + ".java";
}else if (type.equalsIgnoreCase("entityHbm")) {
newJavaFile = project + "/src/model/"
+ className + ".hbm.xml";
}else if (type.equalsIgnoreCase("action")) {
String tblname=className.substring(3); //去掉tbl的类名
tblname=tblname.substring(0, 1).toUpperCase()+tblname.substring(1);
newJavaFile = project + "/src/action/"
+ tblname + "Action.java";
}else if (type.equalsIgnoreCase("list")) {
newJavaFile = project + "/WebRoot/WEB-INF/"
+ "list.jsp";
}else if (type.equalsIgnoreCase("add")) {
newJavaFile = project + "/WebRoot/WEB-INF/"
+ "add.jsp";
}else if (type.equalsIgnoreCase("detail")) {
newJavaFile = project + "/WebRoot/WEB-INF/"
+ "detail.jsp";
}else if (type.equalsIgnoreCase("edit")) {
newJavaFile = project + "/WebRoot/WEB-INF/"
+ "edit.jsp";
}else if (type.equalsIgnoreCase("basicAction")) {
newJavaFile = project + "/src/action/"
+ "BasicAction.java";
String data=readFileByLines(newJavaFile); //读取basicAction文件
String ftlurl = project + "/src/template/basicAction.ftl";
wirteFileByLines(ftlurl,data); //写ftl模板文件
}else{
newJavaFile="";
}
return new String(newJavaFile);
}
/**
* 根据传入的表名生成model模型层
* @return {@link Boolean}
* @param date 当前日期
*/
@SuppressWarnings({ "static-access", "unchecked" })
public void createOneEntity(AutoStartTableEntity aste,String url) {
TemplateUtil tu = new TemplateUtil(url);
// 模板名
List tempNameList = tu.getFileName();
String className = aste.getTableName();
Map map = new HashMap();
map.put("name", className.toLowerCase()); //全小写
map.put("Name", className) ;
map.put("NAME", className.toUpperCase()); //全大写
map.put("list", aste.getTableColumn());
map.put("author", "作者");
map.put("ps", "表名");
map.put("date","2015");
String tblname=className.substring(3); //去掉tbl的类名
map.put("tblname", tblname.toLowerCase()); //全小写action类名
map.put("tblName", tblname.substring(0, 1).toUpperCase()+tblname.substring(1));
for (int j = 0; j < tempNameList.size(); j++) {
String tempName = tempNameList.get(j);
String type = tempName.substring(0, tempName.lastIndexOf("."));
String newJavaFile = null;
newJavaFile = tu.getSavePath(type, url, className);
if(newJavaFile.equals("")){
continue;
}
try {
SpringTemplateUnits.templateAppend(tempName, newJavaFile,
map, tu.getTempPath());
System.out.println("已创建"+className);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
}
/**
* 读basicAction文件返回字符串
* @param filestr
* @return
*/
public String readFileByLines(String filestr) {
BufferedReader reader = null;
String str="";
try {
System.out.println("以行为单位读取文件内容,一次读一整行:");
reader = new BufferedReader(new InputStreamReader(new FileInputStream(filestr),"UTF-8"));
String tempString = null;
int line = 1;
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
tempString+="\r\n";
// 显示行号
if(tempString.equals("\t//自动生成表\r\n")){
tempString+="\t@Resource(name = ${Name}Service.${NAME}_SERVICE_IMPL)\r\n";
tempString+="\tprotected ${Name}Service ${tblname}ser;\r\n";
}
if(tempString.equals("//自动生成导入区域\r\n")){
tempString+="import service.${Name}Service;\r\n";
}
System.out.println("line " + line + ": " + tempString);
str+=tempString;
line++;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
return str;
}
/**
* 写ftl模板文件
* @param filestr
* @param data
*/
public void wirteFileByLines(String filestr,String data) {
try {
File file =new File(filestr);
if(file.exists()){
file.delete();
}
OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
BufferedWriter bufferWritter = new BufferedWriter(write);
bufferWritter.write(data);
bufferWritter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("File Wirte Done");
}
SpringTemplateUnits
类
该文件提供生成java文件的接口
public static String pageEncoding = "UTF-8";
@SuppressWarnings("unchecked")
public static boolean templateAppend(String ftlName, String targetFileName,
Map map, String relPath) throws IOException, TemplateException {
init(ftlName, targetFileName, map, relPath);
return true;
}
@SuppressWarnings("unchecked")
public static void init(String ftl, String targetName, Map map,
String relPath) throws IOException, TemplateException {
Configuration freemarkerCfg = new Configuration();
freemarkerCfg.setDirectoryForTemplateLoading(new File(relPath));
Locale ss=Locale.getDefault();
freemarkerCfg.setEncoding(Locale.getDefault(), pageEncoding);
Template template = freemarkerCfg.getTemplate(ftl, pageEncoding);
template.setEncoding("UTF-8");
File temp = new File(targetName);
String dir = targetName.substring(0, targetName.lastIndexOf("/") + 1);
File dirs = new File(dir);
if (!dirs.exists()) {
dirs.mkdirs();
}
Writer out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(temp), pageEncoding));
template.process(map, out);
out.flush();
out.close();
}
entity.ftl
package model;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="${NAME}")
@SuppressWarnings("serial")
public class ${Name} implements Serializable {
private static final long serialVersionUID = 1L;
<#list list as item>
private ${item.colType} ${item.colName};
#list>
<#list list as item>
<#if item.colName="id">
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
<#elseif item.colName!="id"&&item.colLong="">
@Column(name="${item.colName}",nullable = ${item.colNull} )
<#else>
@Column(name="${item.colName}",length=${item.colLong},nullable = ${item.colNull})
#if>
public ${item.colType} get${item.colUPName}() {
return ${item.colName};
}
public void set${item.colUPName}(${item.colType} ${item.colName}) {
this.${item.colName} = ${item.colName};
}
#list>
}
entityHbm.ftl model类xml文件
<#list list as item>
<#if item.colName!="id"&&item.colLong="">
<#elseif item.colName!="id"&&item.colLong!="">
#if>
#list>
众所周知,jsp一般需要使用到el表达式,而我们的模板中也恰恰使用到el表达式,在生成你的jsp过程中,freemarker会把你jsp中el表达式当做模板中的来使用,这样就会出现错误。如何避免那?把它当做一个普通的字符串就好。
使用${r""}格式来转换。如:${r"${name}"} 看起来很好用不是吗?
有的时候会碰到需要使用到模板自动生成的字段再加上jsp固定的字符串,这怎么来实现?${r""} 同样支持拼接。如:${r"${"}${tblname}${r"."}${item.colName}${r"}"} 看起来很复杂吧.......
在上述类中使用的了我自建立的工具类或者说模型类,它用来记录在网页上所填的表的信息如:列名等等。
AutoStartTableEntity 表模型类
private String tableName; //表名
private List tableColumn; //表列
public AutoStartTableEntity() {
}
public AutoStartTableEntity(String tableName,
List tableColumn) {
this.tableName = tableName;
this.tableColumn = tableColumn;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public List getTableColumn() {
return tableColumn;
}
public void setTableColumn(List tableColumn) {
this.tableColumn = tableColumn;
}
AutoStartColumnEntity 表中的列模型
private String colName; //列明
private String colType; //列类型
private String colUPName; //首字母大写列名
private String colUPERName; //全大写列名
private String colLong; //列长度
private String colAllType; //列全限定类型
private String colNull; //可否为空
private String colJspName; //jsp所用列描述名
public AutoStartColumnEntity() {
}
public AutoStartColumnEntity(String colName, String colType) {
setColName(colName);
setColType(colType);
setColUPName();
}
public String getColName() {
return colName;
}
public void setColName(String colName) {
this.colName = colName.toLowerCase();
}
public String getColType() {
return colType;
}
public void setColType(String colType) {
this.colType = colType;
/**
* 原用于数据库
if(colType.equals("nvarchar")||colType.equals("varchar")||colType.equals("nchar")||colType.equals("char"))
this.colType="String";
if(colType.equals("datetime")){
this.colType="Date";
}
*/
}
public String getColUPName() {
return colUPName;
}
public void setColUPName() {
this.colUPName=this.colName.substring(0,1).toUpperCase()+this.colName.substring(1);
}
public String getColLong() {
return colLong;
}
public void setColLong(String colLong) {
this.colLong = colLong;
}
public String getColUPERName() {
return colUPERName;
}
public void setColUPERName() {
this.colUPERName=this.colName.toUpperCase();
}
public String getColAllType() {
return colAllType;
}
public void setColAllType() {
this.colAllType = "java.lang."+colType;
if(colType.equals("Date")){
this.colAllType="java.util.Date";
}
}
public String getColNull() {
return colNull;
}
public void setColNull(String colNull) {
this.colNull = colNull;
}
public void setColNull() {
if(this.colNull==null||this.colNull.equals("")){
this.colNull="false";
}
}
public String getColJspName() {
return colJspName;
}
public void setColJspName(String colJspName) {
this.colJspName = colJspName;
}
这是我action所做的操作。
public String autoPrint() {
//获取要生成本地项目所在目录
String url=super.getParameter("url");
TemplateUtil tu = new TemplateUtil(url);
List astee=new ArrayList();
//必要预制操作
for (AutoStartColumnEntity col : aste.getTableColumn()) {
if(col!=null){
col.setColUPERName();
col.setColUPName();
col.setColAllType();
col.setColNull();
astee.add(col);
}
}
aste.setTableColumn(astee);
tu.createOneEntity(aste,url);
return SUCCESS;
}
最后上张页面图吧