使用Freemarker解析占位符,构造可执行的SQL语句

背景

最近遇到一个需求, 框架需要执行用户给定的SQL语句,该SQL语句内包含占位符, 占位符表示的内容存在于在框架中,比如下面的sql

select * from xxx where id = ${xxid}

xxid值存在于框架中,也就是说框架需要解析用户设置的sql,将占位符用框架内的值替换。

众所周知,Mybatis能够解析占位符,执行SQL语句, 但是由于sql语句由用户传入,不是写在xmlMybatis的注解中,查阅了Mybatis文档,其并不支持直接执行sql语句, 所以必须考虑如何解析占位符的问题。


解决方法

Freemarker可以基于模板生成输出文本,并且其要求的dataModelObject类型,只要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是可以多层嵌套的,只要字符串内占位符对应的名称对应。

猜你喜欢

转载自blog.csdn.net/sweatott/article/details/75807637
今日推荐