半步多 玄玉的博客

iBatis动态查询及缓存配置

2011-04-05
玄玉

动态查询

ibatis提供了丰富的判定节点,它主要分为一元判定和二元判定两类

一元判定是针对属性值本身的判定,如属性是否为NULL,是否为空值等

以下是比较典型的一元判定

判定节点 描述
<isPropertyAvailable> 参数类中是否提供了此属性
<isNotPropertyAvailable> 与<isPropertyAvailable>相反
<isNull> 属性值是否为NULL
<isNotNull> 与<isNull>相反
<isNotEmpty> 与<isEmpty>相反
<isEmpty> 若属性为Collection或者String,其size是否小于壹相反
其它类型则通过String.valueOf(属性值)获得其String类型的值后,判断其size是否小于壹

下面是其它常见的二元判定节点

判定节点 描述
<isEqual> 相等
<isNotEqual> 不等
<isGreaterThan> 大于
<isGreaterEqual> 大于等于
<isLessThan> 小于
<isLessEqual> 小于等于

下面是动态查询的配置示例

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap>
    <typeAlias alias="user" type="com.jadyer.model.User"/>
    <select id="findByNameOrSex" parameterClass="user" resultClass="user">
        select * from t_user
        <dynamic prepend="WHERE">
            <!--
            prepend属性,指明了本节点中定义的SQL子句在主体SQL中出现时的前缀
            而name属性对应的isNotEmpty节点,ibatis会自动判定是否需要追加prepend前缀
            这里"name = #name#"是WHERE子句中的第一个条件子句,不需要AND前缀,会自动省略
            并且:实际运行期将生成带占位符的PreparedStatement
            -->
            <isNotEmpty prepend="AND" property="name">
                name = #name#
            </isNotEmpty>
            <isNotEmpty prepend="AND" property="sex">
                sex = #sex#
            </isNotEmpty>
        </dynamic>
    </select>
    <select id="findByAddressUseName" parameterClass="user" resultClass="user">
        select * from t_user
        <dynamic prepend="WHERE">
            <!-- 判定节点的定义可以非常灵活,甚至可以使用嵌套的判定节点来实现复杂的动态映射 -->
            <isNotEmpty prepend="AND" property="name">
                (name = #name#
                <isNotEmpty prepend="AND" property="address">
                    address = #address#
                </isNotEmpty>
                )
            </isNotEmpty>
        </dynamic>
    </select>
    <select id="findByAge" parameterClass="int" resultClass="user">
        select * from t_user
        <dynamic prepend="WHERE">
            <!-- 这是一个二元判定。二元判定有两个判定参数,一是属性名,一是判定值 -->
            <isGreaterThan prepend="AND" property="age" compareValue="22">
                age = #age#
            </isGreaterThan>
        </dynamic>
    </select>
</sqlMap>

缓存机制

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap>
    <typeAlias alias="user" type="com.jadyer.model.User"/>

    <!--
    cacheModel节点:定义了本映射文件中使用的Cache机制
    这里申明了一个名为"user-cache"的cacheModel,之后可以在<statement>中对其引用
    与Hibernate类似,ibatis通过缓冲接口的插件式实现,提供了多种Cache的实现机制可供选择
    目前有四种Cache实现:MEMORY、LRU、FIFO、OSCACHE
    -->
    <cacheModel type="LRU" id="user-cache">
        <!-- Cache刷新间隔。间隔时间到了之后,会在下一次查询时,越过Cache直接查数据库,然后才更新Cache -->
        <flushInterval hours="24"/>
        <!--
        当这些statement被执行了,那么下次的查询将会通过SQL去查,同时用查询结果更新Cache
        注意和flushInterval一样,都不是主动刷新,而是由下次查询来触发被动刷新
        在一个cacheModel中可以指定多个flushOnExecute
        -->
        <flushOnExecute statement="updateUser"/>
        <!-- 本CacheModel中最大容纳的数据对象数量 -->
        <property name="size" value="1000"/>
    </cacheModel>

    <select id="findById" parameterClass="int" resultClass="user" cacheModel="user-cache">
        <![CDATA[
            select * from T_USER where id = #id#
        ]]>
    </select>

    <update id="updateUser" parameterClass="user">
        update T_USER set name=#name#, birth=#birth# where id=#id#
    </update>
</sqlMap>

上一篇 iBatis入门例子

Content