对于数据表的操作很大一部分的工作在于查询,可以根据各个字段查询,也可以对一些字段的组合进行查询。如果为每个查询分别写一个接口,那工作量会非常大。IBatisNet提供了动态SQL技术,我们可以利用此技术为每张表提供一个通用的查询接口(只需要一个接口哦)。
假设有一张数据表person如下:
id bigint
name varchar
sex tinyint
birthday date
tel varchar
address varchar
person表对应的内存对象为Class Person{}
首先,为每个字段约定一个无意义的值,例如 字符串为空,数值为0 等。(字段是这些值时,就不根据这些字段进行查询。)
查询语句为:(省去resultMap的定义)
<select id="person_Select" parameterClass="Person" resultMap="Person_Result">
SELECT * FROM person
<dynamic prepend="WHERE">
<isNotEqual prepend="AND" property="id" compareValue="0">[id] = #id#</isNotEqual>
<isNotEmpty prepend="AND" property="name">[name] = #name#</isNotEmpty>
<isNotEqual prepend="AND" property="sex" compareValue="0">[sex] = #sex#</isNotEqual>
<isNotEmpty prepend="AND" property=" tel ">[ tel] = #tel#</isNotEmpty>
<isNotEmpty prepend="AND" property=" address ">[address] = #address#</isNotEmpty>
</dynamic>
</select>
DAO层调用方法为:
IList GetPerson(Person model){ return IBatisNet.QueryForList(“person_Select”, model);}
这样我们只要给传入的Person对象需要查询的字段赋值,其他字段赋予约定的无意义的值,就可以进行各种查询。
例如查询一个叫“张三”的人:
Person p = new Person();
p.name = “张三”;
result = GetPerson(p);
查询电话为“11111111”的人:
Person p = new Person();
p.tel = “11111111”;
result = GetPerson(p);
上面的方法显然还不够灵活,不能根据字符串是否包含,数值或时间大小比较进行查询。譬如想查询“**年之前出生的人”,或“年龄小于**岁的人”,就无法通过如上的一个函数接口来实现了。
为灵活起见,我们可以定义另外一个查询类叫QOPerson有以下属性:
long id = 0;
string name = String.Empty;
string subname = String.Empty;
Period birthdayPeriod = null;
string address = String.Empty;
string subaddress = String.Empty;
………….
(其中Period是具有两个元素begintime,endtime都是datetime类型的)
xml文档查询语句改成:
<select id="person_Select" parameterClass="QOPerson" resultMap="Person_Result">
SELECT * FROM person
<dynamic prepend="WHERE">
<isNotEqual prepend="AND" property="id" compareValue="0">[id] = #id#</isNotEqual>
<isNotEmpty prepend="AND" property="name">[name] = #name#</isNotEmpty>
<isNotEmpty prepend="AND" property=" subname"> ltrim(#subname#, [name]) is null </isNotEmpty>
<isNotNull prepend="AND" property="birthday">
<![CDATA[
[birthday] >= # birthdayPeriod. begintime# AND [birthday] < #birthdayPeriod.endtime#
]]> type="text/javascript"> f(clean);
</isNotNull>
<isNotEmpty prepend="AND" property="address">[address] = #address #</isNotEmpty>
<isNotEmpty prepend="AND" property="address "> ltrim(#subaddress#, [address]) is null </isNotEmpty>
</dynamic>
</select>
DAO层不变。现在可以进行各种查询了。
例如要查询名字里有“张”字的所有人:
QOPerson p = new QOPerson ();
p.subname = “张”;
result = GetPerson(p);
要查询“80年之后”出生的人:
QOPerson p = new QOPerson ();
Period period= new Period();
period.begintime = DateTime.Parse(“1980-01-01”);
period.endtime = DateTime.Now;
p. birthdayPeriod = period;
result = GetPerson(p);