使用Freemarker解析佔位符,構造可執行的SQL語句
阿新 • • 發佈:2018-12-24
背景
最近遇到一個需求, 框架需要執行使用者給定的SQL
語句,該SQL
語句內包含佔位符, 佔位符表示的內容存在於在框架中,比如下面的sql
select * from xxx where id = ${xxid}
xxid
值存在於框架中,也就是說框架需要解析使用者設定的sql
,將佔位符用框架內的值替換。
眾所周知,Mybatis
能夠解析佔位符,執行SQL
語句, 但是由於sql
語句由使用者傳入,不是寫在xml
或Mybatis
的註解中,查閱了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
是可以多層巢狀的,只要字串內佔位符對應的名稱對應。