项目流程
从GenerateConf.xml读取一些必要数据,如路径、实体类名、实体类字段等,在Generate.java这个总控制中心解析后,调用GenerateDao、GenerateService和GenerateModel类的中方法生成所需代码。
在PathUtil中,有一些公共的方法,如判断包路径是否存在,及将模板文件生成为java文件。
以下代码可点击这儿下载
代码
模板文件
dao.ftl
package ${packageName};
<#if !implflag>
import ${modelpackageName}.${className};
public interface ${className}Dao {
public void insert(${className} ${className?lower_case});
public void del(${className} ${className?lower_case});
}
<#else>
import javax.annotation.Resource;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
import ${modelpackageName}.${className};
import ${ImplpackageName};
@Repository("${className?lower_case}Dao")
public class ${className}DaoImpl implements ${className}Dao {
@Resource HibernateTemplate hibernateTemplate;
public void insert(${className} ${className?lower_case}){
hibernateTemplate.save(${className?lower_case});
}
public void del(${className} ${className?lower_case}){
hibernateTemplate.delete(${className?lower_case});
}
}
</#if>
model.ftl
package ${packageName};
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class ${className} {
<#list attrs as a>
private ${a.type} ${a.field}; // ${a.comment}
</#list>
<#list attrs as a>
public void set${a.field?cap_first}(${a.type} ${a.field}){
this.${a.field} = ${a.field};
}
public ${a.type} get${a.field?cap_first}(){
return this.${a.field};
}
</#list>
}
service.ftl
package ${packageName};
<#if !implflag>
import ${modelpackageName}.${className};
import ${daopackageName}.${className}Dao;
public interface ${className}Service {
public void insert(${className} ${className?lower_case});
public void del(${className} ${className?lower_case});
}
<#else>
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import ${modelpackageName}.${className};
import ${daopackageName}.${className}Dao;
import ${ImplpackageName};
@Service("${className?lower_case}Service")
public class ${className}ServiceImpl implements ${className}Service {
@Resource ${className}Dao ${className?lower_case}Dao;
public void insert(${className} ${className?lower_case}){
${className?lower_case}Dao.insert(${className?lower_case});
}
public void del(${className} ${className?lower_case}){
${className?lower_case}Dao.del(${className?lower_case});
}
}
</#if>
生成代码
GenerateConf.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!-- 模板配置
模板文件路径和model、dao、service对应需要的模板名-->
<ftl path="\\src\\com\\shixun\\generate\\ftl">
<param name="model">/model.ftl</param>
<param name="dao">/dao.ftl</param>
<param name="service">/service.ftl</param>
</ftl>
<!-- service.ftl需要的信息
path service包路径
packageName service中的java文件需要指定包名 -->
<service path="\\src\\com\\shixun\\service">
<packageName>com.shixun.service</packageName>
</service>
<!-- dao.ftl需要的信息
path dao包路径
packageName dao中的java文件需要指定包名 -->
<dao path="\\src\\com\\shixun\\dao">
<packageName>com.shixun.dao</packageName>
</dao>
<!-- model.ftl需要的信息
path model包路径
packageName model中的java文件需要指定包名
class 实体类名
field 实体类中的字段
fieldName 字段名
fieldType 字段类型
fieldComment 注释 -->
<model path="\\src\\com\\shixun\\model">
<packageName>com.shixun.model</packageName>
<class>User</class>
<field>
<fieldName>id</fieldName>
<fieldType>int</fieldType>
<fieldComment>id</fieldComment>
</field>
<field>
<fieldName>name</fieldName>
<fieldType>String</fieldType>
<fieldComment>姓名</fieldComment>
</field>
</model>
</root>
PathUtil
java
package com.shixun.generate;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
*
* 这个类功能:
* 1. 用来判断包路径是否存在,若不存在,即创建文件夹;
* 2. 将配好的模板文件写出到指定路径下的文件
* 3. 将配好的模板文件写出到控制台
*/
public class PathUtil {
//判断包路径是否存在
public static void Path_Judge_Exist(String path){
File file = new File(System.getProperty("user.dir"), path);
if(!file.exists()) file.mkdirs();
}
//输出到文件
public static void printFile(Map<String, Object> root, Template template, String filePath, String fileName) throws IOException, TemplateException {
String path = System.getProperty("user.dir") + filePath;
File file = new File(path, fileName + ".java");
if(!file.exists()) file.createNewFile();
FileWriter fw = new FileWriter(file);
template.process(root, fw);
fw.close();
}
//输出到控制台
public static void printConsole(Map<String, Object> root, Template template)
throws TemplateException, IOException {
StringWriter out = new StringWriter();
template.process(root, out);
System.out.println(out.toString());
}
}
Attr
java
package com.shixun.generate;
public class Attr {
private String field; //字段名
private String type; //字段类型
private String comment; //注释
public Attr(String field, String type, String comment){
this.field = field;
this.type = type;
this.comment = comment;
}
public Attr() {}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
Generate
java
package com.shixun.generate;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import freemarker.template.TemplateException;
/**
*
* 总控制中心,在这里读取xml配置的信息,
* 后通过GenerateDao、GenerateService、GenerateModel分别生成Dao层、Service层、Model层所需要的java文件
*/
public class Generate {
public static void main(String[] args) throws IOException, TemplateException, ParserConfigurationException, SAXException {
String ftlPath = "";
String ModelftlName = "";
String fileName = "";
String ModelfilePath = "";
String ModelpackgeName = "";
String DaoftlName = "";
String DaofilePath = "";
String DaopackgeName = "";
String ServiceftlName = "";
String ServicefilePath = "";
String ServicepackgeName = "";
List<Object> modellist = new ArrayList<Object>();
File xmlFile = new File(System.getProperty("user.dir"), "\\src\\com\\shixun\\generate\\GenerateConf.xml");
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document doc = builder.parse(xmlFile);
Element rootElement = doc.getDocumentElement(); //获取根元素
Node ftlnode = rootElement.getElementsByTagName("ftl").item(0);
ftlPath = ((Element)ftlnode).getAttribute("path");
NodeList params = ftlnode.getChildNodes();
for(int i = 0; i < params.getLength(); i++){
Node node = params.item(i);
if(node.getNodeType() != Node.ELEMENT_NODE) continue;
Element e = (Element)node;
if(e.getAttribute("name").trim().equals("model")) ModelftlName = node.getFirstChild().getNodeValue();
if(e.getAttribute("name").trim().equals("dao")) DaoftlName = node.getFirstChild().getNodeValue();
if(e.getAttribute("name").trim().equals("service")) ServiceftlName = node.getFirstChild().getNodeValue();
}
Node servicenode = rootElement.getElementsByTagName("service").item(0);
ServicefilePath = ((Element)servicenode).getAttribute("path");
ServicepackgeName = servicenode.getChildNodes().item(1).getFirstChild().getNodeValue();
Node daonode = rootElement.getElementsByTagName("dao").item(0);
DaofilePath = ((Element)daonode).getAttribute("path");
DaopackgeName = daonode.getChildNodes().item(1).getFirstChild().getNodeValue();
Node modelnode = rootElement.getElementsByTagName("model").item(0);
ModelfilePath = ((Element)modelnode).getAttribute("path");
params = modelnode.getChildNodes();
for(int i = 0; i < params.getLength(); i++){
Node node = params.item(i);
if(node.getNodeType() != Node.ELEMENT_NODE) continue;
Element e = (Element)node;
if(e.getNodeName().trim().equals("packageName")) ModelpackgeName = node.getFirstChild().getNodeValue();
if(e.getNodeName().trim().equals("class")) fileName = node.getFirstChild().getNodeValue();
if(e.getNodeName().trim().equals("field")){
NodeList attrnode = node.getChildNodes();
Attr attr = new Attr();
for(int j = 0; j < attrnode.getLength(); j++){
Node anode = attrnode.item(j);
if(anode.getNodeType() != Node.ELEMENT_NODE) continue;
Element ae = (Element)anode;
if(ae.getTagName().trim().equals("fieldName")) attr.setField(anode.getFirstChild().getNodeValue());
if(ae.getTagName().trim().equals("fieldType")) attr.setType(anode.getFirstChild().getNodeValue());
if(ae.getTagName().trim().equals("fieldComment")) attr.setComment(anode.getFirstChild().getNodeValue());
}
modellist.add(attr);
}
}
generateModel(ftlPath, ModelftlName, fileName, ModelfilePath, ModelpackgeName, modellist);
generateDao(ftlPath, DaoftlName, fileName, DaofilePath, DaopackgeName, ModelpackgeName);
generateService(ftlPath, ServiceftlName, fileName, ServicefilePath, ServicepackgeName, DaopackgeName, ModelpackgeName);
}
private static void generateService(String ftlPath, String serviceftlName, String fileName, String servicefilePath, String servicepackgeName, String daopackgeName, String modelpackgeName) throws IOException, TemplateException {
GenerateService.Generate(ftlPath, serviceftlName, fileName, servicefilePath, servicepackgeName, daopackgeName, modelpackgeName);
}
private static void generateDao(String ftlPath, String daoftlName, String fileName, String daofilePath, String daopackgeName, String modelpackgeName) throws IOException, TemplateException{
GenerateDao.Generate(ftlPath, daoftlName, fileName, daofilePath, daopackgeName, modelpackgeName);
}
private static void generateModel(String ftlPath, String modelftlName, String fileName, String modelfilePath, String modelpackgeName, List<Object> modellist) throws IOException, TemplateException {
GenerateModel.Generate(ftlPath, modelftlName, fileName, modelfilePath, modelpackgeName, modellist);
}
}
GenerateDao
java
public class GenerateDao {
public static void Generate(String ftlPath, String ftlName, String fileName, String filePath, String packageName, String modelpackageName) throws IOException, TemplateException {
String ImplFilePath = filePath + "\\impl";
PathUtil.Path_Judge_Exist(ftlPath);
PathUtil.Path_Judge_Exist(filePath);
PathUtil.Path_Judge_Exist(ImplFilePath);
//实体类需要其他参数
Map<String,Object> root = new HashMap<String, Object>();
root.put("modelpackageName", modelpackageName);
root.put("packageName", packageName);
root.put("className", fileName);
root.put("implflag", false);
Configuration cfg = new Configuration();
String path = System.getProperty("user.dir") + ftlPath;
cfg.setDirectoryForTemplateLoading(new File(path));
Template template = cfg.getTemplate(ftlName);
PathUtil.printFile(root, template, filePath, fileName + "Dao");
//生成Impl文件
root.put("ImplpackageName", packageName + "." + fileName + "Dao");
root.put("packageName", packageName + ".impl");
root.put("implflag", true);
PathUtil.printFile(root, template, ImplFilePath, fileName + "DaoImpl");
}
}
GenerateModel
java
public class GenerateModel {
/**
* @param ftlPath 模板所在路径
* @param ftlName 模板名
* @param fileName model类的名字
* @param filePath model层的路径
* @param packgeName model层的包名
* @param list 实体类字段
*/
public static void Generate(String ftlPath, String ftlName, String fileName, String filePath, String packageName, List<Object> list) throws IOException, TemplateException{
PathUtil.Path_Judge_Exist(ftlPath);
PathUtil.Path_Judge_Exist(filePath);
//实体类需要其他参数
Map<String,Object> root = new HashMap<String, Object>();
root.put("packageName", packageName);
root.put("className", fileName);
root.put("attrs", list);
Configuration cfg = new Configuration();
String path = System.getProperty("user.dir") + ftlPath;
cfg.setDirectoryForTemplateLoading(new File(path));
Template template = cfg.getTemplate(ftlName);
PathUtil.printFile(root, template, filePath, fileName);
}
}
GenerateService
java
public class GenerateService {
public static void Generate(String ftlPath, String ftlName,
String fileName, String filePath, String packageName,
String daopackageName, String modelpackageName) throws IOException, TemplateException {
String ImplFilePath = filePath + "\\impl";
PathUtil.Path_Judge_Exist(ftlPath);
PathUtil.Path_Judge_Exist(filePath);
PathUtil.Path_Judge_Exist(ImplFilePath);
//实体类需要其他参数
Map<String,Object> root = new HashMap<String, Object>();
root.put("modelpackageName", modelpackageName);
root.put("daopackageName", daopackageName);
root.put("packageName", packageName);
root.put("className", fileName);
root.put("implflag", false);
Configuration cfg = new Configuration();
String path = System.getProperty("user.dir") + ftlPath;
cfg.setDirectoryForTemplateLoading(new File(path));
Template template = cfg.getTemplate(ftlName);
PathUtil.printFile(root, template, filePath, fileName + "Service");
//生成Impl文件
root.put("ImplpackageName", packageName + "." + fileName + "Service");
root.put("packageName", packageName + ".impl");
root.put("implflag", true);
PathUtil.printFile(root, template, ImplFilePath, fileName + "ServiceImpl");
}
}
心得
基于前一天对自动生成代码研究的扩展,将生成代码范围覆盖到Service层,Dao层,简单实现对实体类的增和删功能。代码有点冗余。