java模板引擎freemarker
在java工程中,经常会有相似性很强,而且工作量很大的文件。比如,在使用mybatis时,需要构建javabean、实现mybatis的xml文件。这时,我们可以通过使用java模板引擎来自动生成这些文件。
java模板引擎是一个基于模板生成文本输出的工具,大大解放了劳动力。现在比较好的模板引擎有freemarker、beetl、Velocity。这里,我们主要介绍,使用freemarker,根据数据库表自动生成javabean、mybatis的xml文件。
一、freemarker
freemarker通过使用ftl模板文件,并向模板参数传值,生成所需要的文件。freemarker能够生成各种文本:HTML、XML、RTF、Java源代码等等。若使用maven管理工程,找到工程目录下的pom.xml文件,加入对freemarker的引用
<dependencies> <dependency> <groupId>freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.8</version> </dependency>
然后,再来举例说明freemarker如何生成java文件。
1.定义模板文件bean.ftl
public class ${beanName}{ <#list Beans as bean> private ${bean.type} ${bean.name}; </#list> <#list Beans as bean> public void set${'${bean.name}'?cap_first}(${bean.type} ${bean.name}){ this.${bean.name}=${bean.name}; } </#list> <#list Beans as bean> public ${bean.type} get${'${bean.name}'?cap_first}(){ return this.${bean.name}; } </#list> }
2.定义一个FreeMarkerUtil.java文件
import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import freemarker.template.Configuration; import freemarker.template.Template; public class FreeMarkerUtil { private Configuration cfg; public void init() throws Exception { // 初始化FreeMarker配置 // 创建一个Configuration实例 cfg = new Configuration(); // 设置FreeMarker的模版文件位置 cfg.setDirectoryForTemplateLoading(new File("./resource")); } public void process(FreeMarkerUtil hf) throws Exception { Map root = new HashMap(); Map name1 = new HashMap<>(); name1.put("name", "age"); name1.put("type", "int"); Map name2 = new HashMap<>(); name2.put("name", "name"); name2.put("type", "String"); List<Map> attr = new ArrayList<>(); attr.add(name1); attr.add(name2); root.put("beanName", "Bean"); root.put("Beans", attr); String projectPath = "./"; String fileName = "Bean.java"; String savePath = "./src/freeMaker/"; Template template = cfg.getTemplate("Bean.ftl"); hf.buildTemplate(root, projectPath, savePath, fileName, template); } public void buildTemplate(Map root, String projectPath, String savePath, String fileName, Template template) { String realFileName = projectPath + savePath + fileName; String realSavePath = projectPath + "/" + savePath; File newsDir = new File(realSavePath); if (!newsDir.exists()) { newsDir.mkdirs(); } try { // SYSTEM_ENCODING = "UTF-8"; Writer out = new OutputStreamWriter(new FileOutputStream( realFileName), "UTF-8"); template.process(root, out); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { FreeMarkerUtil hf = new FreeMarkerUtil(); hf.init(); hf.process(hf); }
其中,ftl文件放在根目录下的resource文件夹下。
二、应用场景示例
假设我们已经在数据库建了一张表,我们准备用mybatis来使用数据库,那么我们需要生成相应的xml文件,javabean文件。
首先,我们需要设置配置文件来定义一些必要的参数,如数据库ip,要访问的表等信息。
然后,需要连接数据库,获取数据库表中的数据类型。
package YQTBase; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.mysql.jdbc.StringUtils; public class DBAction { public void connectDB(String url,String password,List<String> tableList){ //声明Connection对象 Connection con; //驱动程序名 String driver = "com.mysql.jdbc.Driver"; //MySQL配置时的用户名 String user = "root"; //遍历查询结果集 try { //加载驱动程序 Class.forName(driver); //1.getConnection()方法,连接MySQL数据库!! con = DriverManager.getConnection(url,user,password); if(!con.isClosed()) System.out.println("Succeeded connecting to the Database!"); ResultSet rs = null; DatabaseMetaData dbmd = con.getMetaData(); for(int i = 0;i < tableList.size();i++){ String tableName = tableList.get(i); Map<String,String> beanMap = new HashMap<>(); List<TableCloum> beanList = new ArrayList<>(); rs = dbmd.getColumns(null, "%", tableName, "%"); while (rs.next()) { TableCloum cloum = new TableCloum(); cloum.setAttrName(rs.getString("COLUMN_NAME")); cloum.setCloumName(rs.getString("COLUMN_NAME")); cloum.setAttrType(conversType(rs.getString("TYPE_NAME"))); beanList.add(cloum); } TableCache.setMap(tableName, beanList); } rs.close(); con.close(); } catch(ClassNotFoundException e) { //数据库驱动类异常处理 System.out.println("Sorry,can`t find the Driver!"); e.printStackTrace(); } catch(SQLException e) { //数据库连接失败异常处理 e.printStackTrace(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ System.out.println("数据库数据成功获取!!"); } } private String conversType(String type){ switch(type.toUpperCase()){ case "INT": return "int"; case "VARCHAR": return "String"; case "BIGINT": return "long"; case "DATETIME": return "Date"; default: return ""; } } } class TableCloum{ private String cloumName;//表中的字段名 private String attrName;//bean结构中的变量名 private String attrType;//bean结果中的变量类型 public String getCloumName() { return cloumName; } public void setCloumName(String cloumName) { this.cloumName = cloumName; } public String getAttrName() { return attrName; } public void setAttrName(String attrName) { this.attrName = attrName; } public String getAttrType() { return attrType; } public void setAttrType(String attrType) { this.attrType = attrType; } }
其中,TableList表示需要访问的数据库表的名字,TableCache存放表与其字段的对应关系,可使用HashMap来实现。
接下来,需要实现各种文件对应的ftl,比如要实现xml文件,里面实现一个添加方法。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="${beanName}"> <insert id="add"> INSERT INTO ${tableName} <trim prefix="(" suffix=")" suffixOverrides=","> <#list coloums as coloum> ${coloum.cloumName}, </#list> </trim> VALUES <trim prefix="(" suffix=")" suffixOverrides=","> <#list coloums as coloum> info.${coloum.attrName}, </#list> </trim> </insert> </mapper>
如上所示,参考第一部分freemarker的使用方法,我们将由数据库表中读到的字段,作为一个List<TableCloum>传给xml的ftl,然后就可以生成mybatis所需要的xml文件。