模拟和改进ibatis中对sql语句的动态替换

4 篇文章 0 订阅

由于要自己解析xml文件,就得亲自动手去动态解析其中的sql语句。原来用惯了ibatis的sql写法,以为解析这种动态sql也很easy的,but,我太年轻了。真正自己去动手写的时候才发现,要替换成一句正常的sql语句要考虑的情况很多。如:字符串替换要不要加引号,对数字的判别,若要遍历的话要怎么考虑,若要进行判断的话又要怎么解析。。。。

哗啦啦的汗死了。。。。

灵机一动,想到了去模仿ibatis怎么处理这些sql的,一开始到网上搜,但是不看源码只看别人的博客还是不懂。于是,开始打开ibatis的源码看sql有关的类。

具体过程就不说了,反正也挺晕的,结果倒是给了我惊喜。

模拟:

首先,对于##和$$这两种特殊的字符替换有了了解,##表示将参数按类型进行替换,比如是字符串则自动加上引号;而$$则是直接替换,不管是什么类型直接替换成值。后来,越看越深入,发现ibatis中其实用到了PreparedStatement,也就是说,它可能是先将变量换成?再调用的Java的方法将值替换。这样就会有冲突,因为全替换为?再执行的话,对于所有的字符串都会自动添加引号,那样一些不需要引号的地方也会被加上而造成sql出错。带着疑惑,慢慢思考,假设$$是直接替换成值,那样字符串也就没加引号了。所以,我大胆假设,ibatis中对$$则替换成值,对于##则替换成?,再调用java的PreparedStatement赋值。而且,得先将##替换成?再替换$$,因为若先替换$$,则可能替换的值中存在#符号而造成##替换时的错误。

改进:

原本以为这样就over了,但后来又发现ibatis中其实不止有这样简单的提花,还可能会有iterator遍历,isNotEmpty这样的节点。当然这样的节点,我们在ibatis的sql动态编写中用起来很方便,所以我也先在我xml中引入这些特性。仔细分析,iterator就是也循环,而isNotEmpty就是也个判断,实现起来并不难。而且,我可以对其改进,因为ibatis中iterator只支持List或数组,我可以把Map也加进去,用key[]和value[]来表示当前遍历的键与值,而List与数组,则可以是下标表示key,值表示value。对于isNotEmpty,只能判断单一情况,可以在此基础上进行扩充,一个判断节点或属性来判断event="a==b"是否为true。

有想法才能实现,最终,也把这点小想法实现了,小功一件。

<sql retVar=""><!-- 根据sql语句确定CRUD调用,根据返回结果确定retVar的类型 -->
	select * from $RQ_table$
	where 0=1
	<iterator var="myMap">
		<step preposition=" (" conjunction=" or " postposition=")">
			(crm_cati_questionnaire.stream_number = #_value_#)
		</step>
	  </iterator>
	  <step preposition=" and " event="corpId != '' && corpId != 'null'">
	  	corpId=#corpId#
	  </step>
	  limit 10,1
</sql>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值