前段时间在开发Eclipse插件中要根据一个已有的表生成对应的前后台操作文件(Java,jsp,xml),选用了Apache的Velocity来实现,当然了这个模板引擎可以用运载更多的需要动态生成代码(或者代码片段的地方)。
下载使用说明和相应的jar包:http://download.csdn.net/detail/lohocc/8462739
在这里只对Velocity的一些简单概念做基本描述
1.什么是Velocity
Velocity是一个基于java的模板引擎(templateengine). 它可以让视图的设计者在web页面中引用java代码中定义的数据对象和命令。从而使Webdesigners和java开发者依照MVC思想(Model-View-Controller)开发系统,这意味着Webdesigners只须将精力注用于良好表现力的视图外观设计,而Java程序员则只要关心着如何写出高效简洁的java对象以实现业务逻辑----- Velocity会将他们组装到一起.相比传统的jsp、PHP等脚本语言,Velocity彻底的将避免了在视图设计中出现的java代码,从而保证了website的长期可维护性.一定要理解,Velocity是一个templateengine的意思,它还可以从模板中生成SQL语句或其它脚本提供给webpages. 它也可以独立使用---做为一个工具类(utilityclass)用来生成源代码、报表、邮件模板等。
2.Velocity能为你做什么
Velocity做为一个相当优秀的模板引擎,能根据我们给定的模板文件(*.vm文件,动态生成部分使用VelocityTemplate Language编写),动态的生成代码片段,相信使用过JSP(Java动态页面)或者freemarker(java编写的另外一种模板引擎技术)对这种技术再熟悉不过了。
3.VelocityTemplate Language (VTL)
TheVelocity Template Language (VTL) 目标是提供一个简洁,易学的方法将动态内容展现到 webpage 上 . a webpage 设计者可以没有任何编程经验就可以在一天内学会使用它增强你的站点的展示力! .VTL使用引用(references)这种方式将dynamiccontent(动态内容,一般指java代码生成的数据对象)加入到你的website,Velocity中的变量(variable)只是refernce中的一种.Variables是用来描述从引入到视图模板中的java数据对象。当然,java代码也可以从模板的VTL中获取数据.以下是一个写在HTML中的VTL变量:#set($a = "Velocity" )。
关于如何使用VTL去声明变量,方法可以参照上面链接里的说明文档。
下面我们来看一个使用一个模板动态生成一个Pojo类:
我来假设这样一个场景,我们通过SQL查出来一个数据库表的所有信息,并存放在一个类中,我们现在根据存放这些信息的类动态生成一个pojo类,并导入需要的类
package velocity;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
public class VelocityTest {
public static class CreateInfo{
private String packageName;
private List<String> importClasses;
private List<ColumnInfo> columns;
private String className;
public void addImportClasses(String classPath){
if(importClasses==null)
importClasses = new ArrayList<String>();
importClasses.add(classPath);
}
public void addColumns(ColumnInfo info){
if(columns==null)
columns = new ArrayList<ColumnInfo>();
columns.add(info);
}
public List<ColumnInfo> getColumns(){
return columns;
}
public List<String> getImportClasses(){
return importClasses;
}
public void setClassNm(String className){
this.className = className;
}
public String getClassNm(){
return className;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
}
public static class ColumnInfo{
private final String cType;
private final String name;
public ColumnInfo(String cType,String name) {
this.cType = cType;
this.name = name;
}
public String getCType() {
return cType;
}
public String getName() {
return name;
}
}
public static void main(String[] args) {
try {
//init createInfo
CreateInfo createInfo = new CreateInfo();
createInfo.setPackageName("com.lohocc");
createInfo.addImportClasses("java.util.Date");
createInfo.setClassNm("Person");
createInfo.addColumns(new ColumnInfo("String", "name"));
createInfo.addColumns(new ColumnInfo("Date", "createDate"));
Template template = Velocity.getTemplate("temple/vo.java.vm");
VelocityContext vcontext = new VelocityContext();
File f = new File("src/com/lohocc/Person.java");
if(!f.exists()){
if(!f.getParentFile().exists()){
f.getParentFile().mkdirs();
}
f.createNewFile();
}
FileWriter writer = new FileWriter(f);
//放入参数
vcontext.put("createInfo", createInfo);
//生成代码片段
template.merge(vcontext, writer);
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面的代码中CreateInfo类可以理解成存储了我们数据库表对应的所有信息(ColumnInfo为字段信息),在main方法中我们伪造了这些相关的信息
模板文件vo.java.vm:
package $createInfo.getPackageName();
#foreach( $impcls in $createInfo.getImportClasses() )
import $impcls;
#end
public class $createInfo.getClassNm(){
#foreach( $col in ${createInfo.getColumns()} )
private ${col.getCType()} ${col.getName()};
#end
#foreach( $col in ${createInfo.getColumns()} )
public ${col.getCType()} get${col.getName()}(){
return ${col.getName()};
}
public void set${col.getName()}(${col.getCType()} ${col.getName()}){
this.${col.getName()} = ${col.getName()};
}
#end
}
在这里调用了传入的createInfo对象并调用了它的方法
看看运行结果(是不是跟很多ORM框架自动生成的类一样):
Velocity提供给了我们简单的VTL写法,使我们很容易根据需要去定制需要生成的代码片段