1. 程式人生 > >使用Freemarker解析佔位符,構造可執行的SQL語句

使用Freemarker解析佔位符,構造可執行的SQL語句

背景

最近遇到一個需求, 框架需要執行使用者給定的SQL語句,該SQL語句內包含佔位符, 佔位符表示的內容存在於在框架中,比如下面的sql

select * from xxx where id = ${xxid}

xxid值存在於框架中,也就是說框架需要解析使用者設定的sql,將佔位符用框架內的值替換。

眾所周知,Mybatis能夠解析佔位符,執行SQL語句, 但是由於sql語句由使用者傳入,不是寫在xmlMybatis的註解中,查閱了Mybatis文件,其並不支援直接執行sql語句, 所以必須考慮如何解析佔位符的問題。

解決方法

Freemarker可以基於模板生成輸出文字,並且其要求的dataModel

Object型別,只要sql語句的佔位符名字存在於dataModel中,就能夠將佔位符替換為具體的值。佔位符需要使用${}修飾。
注意點: 使用Freemarker API,上下文裡佔位符對應的值如果為Null,會丟擲一個異常。

具體操作

Configuration cfg = new Configuration(Configuration.VERSION_2_3_26);
cfg.setDefaultEncoding("UTF-8");
cfg.setNumberFormat("computer");
  • 設定編碼格式
  • 設定number的格式,這一步比較重要,因為Freemarker
    解析出來的整數是每3位帶逗號的,也就會導致sql執行失敗。computer格式相當於Freemarker模板語法的c,即someNumber?c,這樣解析出來的整數是不帶逗號的。
Template template = new Template("tempTest", YourStr, cfg);
  • 獲取模板,第一個引數為模板名,第二個引數為需要解析的字串,第三個引數為配置
Writer out = new StringWriter();
template.process(dataModel, out);
out.toString();
  • dataModel存在和佔位符同名的變數
  • process()方法進行解析,同時將結果寫入out,最後執行out.toString()就可以獲得解析後的字串

第一次接觸到Freemarker,感覺非常好用,尤其是它的dataModel是可以多層巢狀的,只要字串內佔位符對應的名稱對應。