背景
最近遇到一个需求, 框架需要执行用户给定的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是可以多层嵌套的,只要字符串内占位符对应的名称对应。
本文介绍了一种利用Freemarker解析SQL语句中的占位符的方法,以便于执行动态SQL。通过设置Configuration并利用dataModel,实现了占位符到实际值的转换。
875

被折叠的 条评论
为什么被折叠?



