1. 程式人生 > >freemarker的DatabaseTemplateLoader從資料庫中獲取模板資訊

freemarker的DatabaseTemplateLoader從資料庫中獲取模板資訊

import com.kingnet.xyzs.orm.dao.DmsMdTemplateConfigMapper;
import com.kingnet.xyzs.orm.entity.DmsMdTemplateConfig;
import freemarker.cache.TemplateLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Reader;
import java.io.StringReader;

/**
 * Created by xiaoj on 2016/9/8.
 */
@Component("databaseTemplateLoader")
public class DatabaseTemplateLoader implements TemplateLoader {

    @Autowired
    private DmsMdTemplateConfigMapper dmsMdTemplateConfigMapper;//注入了一個mybatis dao mapper

    @Override
    public Object findTemplateSource(String name) {
        try {
            Integer templateId = Integer.valueOf(name);
            //通過id查詢資料庫中配置的模板資訊
            DmsMdTemplateConfig config = dmsMdTemplateConfigMapper.selectByPrimaryKey(templateId);
            //資料庫表必須有一個最後更新欄位用來重新整理快取,資料庫中的模板儲存欄位為query,這裡通過model.getQuery獲取
            return new StringTemplateSource(name, config.getQuery(), config.getUpdatetime().getTime());
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public long getLastModified(Object templateSource) {
        return ((StringTemplateSource) templateSource).lastModified;
    }

    @Override
    public Reader getReader(Object templateSource, String encoding) {
        return new StringReader(((StringTemplateSource) templateSource).source);
    }

    @Override
    public void closeTemplateSource(Object templateSource) {
        //do nothing
    }

    private static class StringTemplateSource {
        private final String name;
        private final String source;
        private final long lastModified;

        StringTemplateSource(String name, String source, long lastModified) {
            if (name == null) {
                throw new IllegalArgumentException("name == null");
            }
            if (source == null) {
                throw new IllegalArgumentException("source == null");
            }
            if (lastModified < -1L) {
                throw new IllegalArgumentException("lastModified < -1L");
            }
            this.name = name;
            this.source = source;
            this.lastModified = lastModified;
        }

        public boolean equals(Object obj) {
            if (obj instanceof StringTemplateSource) {
                return name.equals(((StringTemplateSource) obj).name);
            }
            return false;
        }

        public int hashCode() {
            return name.hashCode();
        }
    }

    @Override
    public String toString() {
        return "DatabaseTemplateLoader(db=\"db_stat\", table=\"DMS_MD_TEMPLATE_CONFIG\")";
    }


}

freemarker 配置:

 <!-- 配置freeMarker的模板路徑 -->
    <bean id="freemarkerConfig" name="freemarkerConfig"
          class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/WEB-INF/templates/"/>
        <!-- 自定義資料庫TemplateLoader -->
        <property name="postTemplateLoaders" ref="databaseTemplateLoader" />
        <property name="freemarkerVariables">
            <map>
                <entry key="xml_escape" value-ref="fmXmlEscape"/>
                <!--<entry key="webRoot" value="${webRoot}"/>-->
                <!--<entry key="jsRoot" value="${jsRoot}"/>-->
            </map>
        </property>
        <!-- FreeMarker預設每隔5秒檢查模板是否被更新,如果已經更新了,就會重新載入並分析模板。 但經常檢查模板是否更新可能比較耗時。如果你的應用執行在生產模式下,而且你預期模板不會經常更新,
            則可以將更新的延遲時間延長至一個小時或者更久。 可以通過為freemarkerSettings屬性設定template_update_delay達到這一目的 -->
        <property name="freemarkerSettings">
            <props>
                <prop key="template_update_delay">5</prop>
                <prop key="tag_syntax">auto_detect</prop>
                <!-- 設定標籤型別 兩種:[] 和 <> 。[] 這種標記解析要快些 -->
                <prop key="default_encoding">UTF-8</prop>
                <prop key="output_encoding">UTF-8</prop>
                <prop key="locale">zh_CN</prop>
                <prop key="date_format">yyyy-MM-dd</prop>
                <prop key="time_format">HH:mm:ss</prop>
                <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                <prop key="number_format">#</prop>
                <!-- 設定數字格式 以免出現 000.00 -->
                <prop key="classic_compatible">true
                </prop>
                <!-- 可以滿足一般需要。預設情況變數為null則替換為空字串,如果需要自定義,寫上${empty!"EmptyValue of fbysss"}的形式即可  -->
                <prop key="template_exception_handler">html_debug</prop>
                <!-- ignore,debug,html_debug,rethrow -->
            </props>
        </property>
        <!-- 一下語句可以也可以配置freemarkerSettings屬性,程式碼更為簡潔 -->
        <!-- <property name="freemarkerSettings" ref="freemarkerConfiguration"></property> -->
    </bean>

    <!--<bean id="freemarkerConfiguration"-->
    <!--class="org.springframework.beans.factory.config.PropertiesFactoryBean">-->
    <!--<property name="location" value="classpath:conf/freemarker.properties" />-->
    <!--</bean>-->

    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>
主要是這個屬性,配置上為自己的databaseTemplateLoader:
 <!-- 自定義資料庫TemplateLoader -->
        <property name="postTemplateLoaders" ref="databaseTemplateLoader" />

獲取模板內容:

FreeMarkerConfigurer freemarkerConfig = applicationContext.getBean("freemarkerConfig", FreeMarkerConfigurer.class);
        Configuration cfg = freemarkerConfig.getConfiguration();
//        String templatePath = submitJobRequest.getProject() + "." + submitJobRequest.getTemplate() + ".ftl";
//        Template temp = cfg.getTemplate(templatePath);
        Template temp = cfg.getTemplate(submitJobRequest.getId());
        StringWriter writer = new StringWriter();
        temp.process(delegate, writer);
        String query = writer.toString();
        writer.close();

程式碼貼上的不全,其他的一些javabean就不粘貼出來了,大家主要看關鍵部分就行了.