改建iBatis,使其支持自动生成sql语句(1)
什么是iBatis:
使用ibatis 提供的ORM机制,对业务逻辑实现人员而言,面对的是纯粹的Java对象, 这一层与通过Hibernate 实现ORM 而言基本一致,而对于具体的数据操作,Hibernate 会自动生成SQL 语句,而ibatis 则要求开发者编写具体的SQL 语句。相对Hibernate等 “全自动”ORM机制而言,ibatis 以SQL开发的工作量和数据库移植性上的让步,为系统 设计提供了更大的自由空间。作为“全自动”ORM 实现的一种有益补充,ibatis 的出现显 得别具意义。
使用iBatis开发项目工作量比较大,因为每个sql语句都必须自己写。一般的CRUD sql都是sql 92规范,基本上都通用所有数据库。我想如果可以通过hack ibatis源代码实现自动生成iql(ibatis sql)可以简化多少开发量啊。(最开始有这个想法是因为ibatis for .net实现了这个功能,而ibatis for java没有)
说干就干,决定依照ibatis for .net的实现方式来实现,通过sql-map的parametermap来实现。以最小代码来实现该功能。
查看了相关dtd后,发现《parameter》节点没有column定义,《parameterMap》节点没有extends定义,《result》和《resultMap》这倒是有。于是修改dtd定义和BasicParameterMapping类,使其支持column。并且修改SqlMapParser类,使其初始化的时候支持column和extends。加入column的目的是为了支持java属性对应到不同的字段上。加入extends的目的是为了重用parametermap。
parameter修改完成后,就要修改dtd文档定义,使其支持《generate》节点,我们只需要《insert》、《update》、《delete》、《select》这四个节点支持就行,《statement》和《sql》节点考虑在下一版支持。generate需要三个属性,分别是table、where、excludes。其中table表示是对应的表,适用于所有;where表示查询条件字段,适用于select、update、delete;excludes表示要排除哪些parameter,适用于select、update。
dtd文档定义修改完成后,就可以修改ibatis加载类,使其支持generate。这个切入点比较难找,因为要仔细分析他的源代码。经过仔细思考后,发现ibatis和sql-map支持《include》,决定在include后面加入generate的解析代码。这样比较方便的找到了切入点。
找到SqlStatementParser类,找到了parseDynamicTags方法,里面就有include的解析。这里面的判断代码是else if,我再加入一个generate的else if 就OK啦。经过一天的修改,完成。工作量也不是太大。
哈哈,下篇日志发布出hack过后的ibatis代码和demo。
原创文章,如果要转载请注明出处、原始地址和作者信息。
2、hibernate对动态sql语句支持不好。
3、何必去浪费时间学习hql?不如去专心研究native sql。
我们的项目四年前就不在写在java代码中了,
一开始是struts项目,现在做的项目公司让选Hibernate或者iBatis
我选择i,抛弃H。
Hibernate最大的缺点是过犹不及。事事讲究封装、对象化,在C++中性能上可能不明显,在JAVA中,特别是大项目中,这种分配内存生成对象很耗时的平台中,将是非常明显的。
Hibernate不错,是因为在小项目中。
如果在大项目中(几百人月以上的)千万不要因为少写几行代码而图方便使用H,否则,一旦出现性能问题,想哭都找不到地方。
<p>1、我喜欢procedure,<br/>
2、我喜欢ibatis的动态SQL。<br/>
3、我不喜欢把sql(或者hql)语句写到java代码中。<br/>
</p>
<div class='code_title'>sqlmap.xml 代码
<div class='code_title'/>
<div class='dp-highlighter'>
<div class='bar'/>
<ol class='dp-xml'>
<li class='alt'><span><span class='tag'><</span><span class='tag-name'>select</span><span> </span><span class='attribute'>id</span><span>=</span><span class='attribute-value'>"getPromotionsByShopCount"</span><span> </span><span class='attribute'>parameterClass</span><span>=</span><span class='attribute-value'>"Query"</span><span> </span><span class='attribute'>resultClass</span><span>=</span><span class='attribute-value'>"int"</span><span class='tag'>></span><span> </span></span></li>
<li class=''><span> select count(*) as value from promotion </span></li>
<li class='alt'><span> </span><span class='tag'><</span><span class='tag-name'>isGreaterThan</span><span> </span><span class='attribute'>property</span><span>=</span><span class='attribute-value'>"userid"</span><span> </span><span class='attribute'>prepend</span><span>=</span><span class='attribute-value'>"where"</span><span> </span><span class='attribute'>compareValue</span><span>=</span><span class='attribute-value'>"0"</span><span class='tag'>></span><span> </span></li>
<li class=''><span> </span><span class='attribute'>shopId</span><span> = #userid# </span></li>
<li class='alt'><span> </span><span class='tag'></</span><span class='tag-name'>isGreaterThan</span><span class='tag'>></span><span> </span></li>
<li class=''><span/><span class='tag'></</span><span class='tag-name'>select</span><span class='tag'>></span><span> </span></li>
</ol>
</div>
</div>
<p><br/>
我喜欢这种风格的代码,ibatis提供的动态sql代码支持太棒了。</p>
<p> </p>
<p>我同意!</p>
http://ibatis.apache.org/tools/abator
感谢作者给我思路,我现在在整理权限系统,ORM用的是IBATIS,如何控制到数据权限是个难题,这样也是动态控制ibatis所生成sql的好法子。