自定义freemarker模板的使用

Usage of custom freemarker template

我想知道是否有人可以帮助我使用 Apache FreeMarker?我正在尝试使用自定义模型,但我无法弄明白。

假设我想转储查询结果(java FreeMarker 模板中的结果集)。什么是最好的方法?

我在 Google 上找到了 class:ResultSetTemplateModel

import java.sql.ResultSet;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateSequenceModel;


public class ResultSetTemplateModel implements TemplateSequenceModel {

    private ResultSet rs = null;
    public ResultSetTemplateModel(ResultSet rs) {
        this.rs = rs;
    }
    public TemplateModel get(int i) throws TemplateModelException {
        try {
            rs.next();
        } catch(Exception e) {
            throw new TemplateModelException(e.toString());
        }
        TemplateModel model = new Row(rs);
        return model;
    }

    public int size() throws TemplateModelException {
        int size=0;
        try {
            rs.last();
            size = rs.getRow();
            rs.beforeFirst();
        } catch (Exception e ) {
            throw new TemplateModelException( e.toString());
        }
        return size;
    }


    class Row implements TemplateHashModel {

        private ResultSet rs = null;
        public Row(ResultSet rs) {
            this.rs = rs;
        }

        public TemplateModel get(String s) throws TemplateModelException {
            TemplateModel model = null;
            try {
                model = new SimpleScalar( rs.getString(s) );
            } catch (Exception e) { e.printStackTrace(); }
            return model;
        }

        public boolean isEmpty() throws TemplateModelException {
            boolean isEmpty = false;
            if ( rs == null ) { isEmpty = true; }
            return isEmpty;
        }

    }
}

我有一个非常简单的class(我什至比以前更简单):

public static void main(String[] args) {

    try {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_27);
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        cfg.setClassForTemplateLoading(MyCLASS.class, "/");
        StringWriter out = new StringWriter();
        Map<String, Object> parameters = new TreeMap<>();

        ResultSet rs = getResultSet("Select foo, bar FROM my_table");
        parameters.put("hello", "World");
        parameters.put("result", rs);


        Template temp = cfg.getTemplate("template.txt");
        temp.process(parameters, out);

        System.out.println("out = " + out);
    } catch (IOException | TemplateException e) {
        e.printStackTrace();
    }

}

我的模板

Hello ${hello}
<#-- how do I specify ResultSet columns here ?? -->

如何使用自定义模板??有什么建议吗??我知道如何加载模板文件。但是不知道怎么在模板里指定是自定义模型

谢谢大家的支持:)

有两种使用ResultSetTemplateModel包装ResultSet-s的方法:

  • 要么通过覆盖 handleUnknownType 来扩展 DefaultObjectWrapper,如果 objResultSet,那么 return new ResultSetTemplateModel((ResultSet) obj) ,否则调用 super。然后用Configuration.setObjectWrapper实际用起来

  • 或者,将 new ResultSetTemplate(rs) 添加到 parameters 而不是 rs;如果某物已经是 TempalteModel,则不会再次包装。请注意,如果您从模板中的其他地方获得 ResultSet,此方法将不起作用,因为它避免了您的手动换行,因此扩展 DefaultObjectWrapper 通常是您想要的。

请注意,显示的 ResultSetTemplateModel 实现非常有限。 ObjectWrapper 也应该传递给构造函数,并存储在 final 字段中。然后,而不是 new SimpleScalar( rs.getString(s) ) 它应该做 objectWrapper.wrap(rs.getObject(s)).