欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java模板引擎freemarker

程序员文章站 2022-03-07 22:34:13
...

  在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文件。