`
yjhexy
  • 浏览: 327260 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

Ibatis 再议动态查询语句

阅读更多

一,ibatis 的<isNotNull>标签。


当属性不为空的时候可以插入。这个时候你是否有过疑问。

如果属性为原生类型 (例如int类型)怎么办?

查看了Ibatis的文档可以发现如果原生类型的话,那么这个标签就显得力不从心了。为什么?

因为原生类型肯定有值,不可能为空。

比如有这么个DO类:

 

public class BabyDO implements Serializable {

	private static final long serialVersionUID = -579987226803641422L;
	private int id;
	private String name; // 姓名
	private SexEnum sex; // 性别
	private Date birthday; // 生日
	private String hobby; // 喜好
	private int age; // 年龄 注意这里是原生类型
	private List<AddressDO> address; // 地址复杂类型

// getters and setters 省略

 

然后有这么个XML代码:

 

<update id="updateBabysPartitialByParams" parameterClass="baby">
		update Baby set
		<dynamic prepend=" ">
			 <isNotNull property="name" prepend='",">
					name=#name#
			    </isNotNull>
			<isNotNull property="sex" prepend=",">
				sex=#sex#
			</isNotNull>
			<isNotNull property="birthday" prepend=",">
				birthday=#birthday#
			</isNotNull>
			<isNotNull property="hobby" prepend=",">
				hobby=#hobby#
			</isNotNull>
			<isNotNull property="age" prepend=",">
				age=#age#
			</isNotNull>
		</dynamic>
		where id = #id#
	</update>

 

那么isNotNull将不起任何作用。

 

读者可以自己尝试一下。


那么同时可想而知 <isNotEmpty>这个标签对原生类型也是不起作用的。读者可以再度尝试将<isNotNull>标签改成<isNotEmpty>标签。

 

 

二,你可能已经注意到上面的XML中有个<dynamic prepend=" ">

 

这个是不是多余的?

 

我曾有这种疑惑,但是当你把他去掉的时候错误也随之而来了。

看了日志居然打印出这种SQL来:

 

2009-09-21 21:47:14,873 DEBUG [java.sql.PreparedStatement] - {pstm-100001} Executing Statement:    update Baby set       ,           name=?                             ,     age=?          where id > 10

 

 

跟踪了好久代码没看懂,到底是哪里的问题,可能我读代码的能力有限。所以查了google,终于找到原因了:

http://issues.apache.org/jira/browse/IBATIS-430

显然已经有人发现了这个现象,并提出了疑问。最终代码到底什么问题我确实是没找到,但是这个现象的确是存在的。


于是在使用的时候就要注意了 。


1,dynamic标签 如果要使标签里面的内容的第一个prepend无效,那么必须要有dynamic标签的prepend属性即使是空的

2,dynamic标签的prepend属性还不能真的为空,至少要一个空格!!!


尝试到这里我还真是有点吐血,看到很早有人提的这个BUG,却没有人去修正。

 

 

 

 

分享到:
评论
2 楼 yjhexy 2010-08-30  
luofuxing 写道
这不是bug,而是ibatis很方便的特性,看看ibatis开发指南中的原话:
<dynamic>元素和条件元素都有“prepend”属性,它是动态SQL代码的一部分,在必要情况下,可以被父元素的“prepend”属性覆盖。……prepend属性……将覆盖第一个为“真”的条件元素。这对于确保生成正确的SQL语句是有必要的。例如,在第一个为“真”的条件元素中,“AND”是不需要的,事实上,加上它肯定会出错。


其实我觉得奇怪的是为什么一定要空格,另外apache官网也open了这个BUG
1 楼 luofuxing 2010-08-27  
这不是bug,而是ibatis很方便的特性,看看ibatis开发指南中的原话:
<dynamic>元素和条件元素都有“prepend”属性,它是动态SQL代码的一部分,在必要情况下,可以被父元素的“prepend”属性覆盖。……prepend属性……将覆盖第一个为“真”的条件元素。这对于确保生成正确的SQL语句是有必要的。例如,在第一个为“真”的条件元素中,“AND”是不需要的,事实上,加上它肯定会出错。

相关推荐

Global site tag (gtag.js) - Google Analytics