mybatis 动态sql语句实现多条件查询(foreach的使用)

一、前言

现有一个需求:实现多条件、不确定条件的搜索功能。

类似于淘宝网进行搜索商品的时候,可以在搜索框进行模糊搜索,同时可以进行条件筛选,例如想买一只 口红? 的时候,可以在搜索框内输入“口红”,还可以选择品牌、否包邮、价格区间等等。。最后搜索出来的结果是满足所有筛选的条件的。

这里我认为的难点就是:这些条件你不确定需不需要,你不确定选了几个,所以说这些都动态的。

我总结了一句话来进行概括:同类型条件取并集,不同类型条件取交集

二、前台界面(了解需求)

页面默认加载全部数据



当有搜索条件后,取满足所有条件的数据:试题内容中包括关键字”程序“、试题类型为”判断题“、所属知识点为”关系运算符、对象的概念“。

这里前台使用了easyui框架、下拉框多选技术、easyUI分页技术参考我的这两篇博文:



在本页面可以看出,在所有试卷中,可以通过关键字搜索试题内容,通过复选下拉框筛选”试题类型“、”所属知识点“这两种条件。

三、mybatis sql语句

这个sql涉及到了三张表的查询,其中还包括嵌套查询。写这个之前真的没想到自己能写出这么复杂的sql语句。
暂时还没考察其健壮性,现在就是把功能都实现了。

把sql语句贴出来:

<select id="selectAllQuestions" resultType="java.util.Map">
        SELECT <include refid="Extend_Column_List"/>, kp.kp_title as kp_value, sys.code_text as question_type_value
        FROM aim_test_questions qt
        inner join amc_knowledgepoint_base_t kp
        on qt.belong_kpcode = kp.kp_code and qt.question_state = '1'
        inner join sys_code_t sys
        on sys.code_data = qt.question_type and sys.code_kind_1 = '试题类型'
        <where>
            <if test="question_content != null and question_content != ''">
                and question_content LIKE CONCAT(CONCAT('%',#{question_content}),'%')
            </if>
            <if test="kp_title!=null and kp_title.size!=0">
                and qt.belong_kpcode in (
                SELECT kp.kp_code
                FROM amc_knowledgepoint_base_t kp
                <where>
                    kp.kp_title in
                    <foreach collection="kp_title" index="index" item="item" open="(" separator="," close=")">
                    #{item}
                    </foreach>
                </where>
                )
            </if>
            <if test="code_text!=null and code_text.size!=0">
                and qt.question_type in (
                SELECT sys.code_data
                FROM sys_code_t sys
                <where>
                    sys.code_text in
                    <foreach collection="code_text" index="index" item="item" open="(" separator="," close=")">
                    #{item}
                    </foreach>
                </where>
                )
            </if>
        </where>
        order by qt.question_create_time asc
 </select>
where前面的不用看,主要看<where>里面有三个<if>。这就是”不同类型条件取交集“,所以这里用到了
<where>
 <if>

 </if>
 <if>

</if>
<if>

</if>
</where>这样的结构来对条件进行筛选。

第一个<if>实现了关键字的模糊搜索。

第二个<if>由于涉及到了另一张表的条件查询,所以用到了嵌套查询。
在前台,下拉框的条件值可以为多个。所以前台会给后台传一个list,其中 kp_title 是用来存放第一个下拉框的值的一个Map。
在这个嵌套语句里面用到了<foreach></foreach>,可以对map、list、array这三种数据类型进行遍历。在本栗子中,

<foreach collection="kp_title" index="index" item="item" open="(" separator="," close=")">
    #{item}
</foreach>
collection里面的kp_title为map的key值。item是用来遍历map的value值的一个别名。

第三个<if>与第二个的内容相似,只不过是又多关联查询了第三张表。


四、总结

当时写这个sql语句真可谓是”吭哧瘪肚“呀,哈哈。其实现在想想也不难。重要的是要把需求先捋清楚。
然后mybatis的sql语句不要着急直接往里面写。可以先在数据库里面把sql语句敲一遍,确认无误后,再写mybatis。

遇到像上面这种需求比较多的,可以把需求拆分。例如先把一个模糊搜索的功能实现。然后再实现其他的功能。

感觉当时写这个的时候有点费劲,所以想贴出来给大家分享,如果不对的地方希望各位大牛能多多指正,大家一起交流一起进步。




评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值