一、前言

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

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

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

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

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


页面默认加载全部数据





根据两个条件批量查询 mysql_搜索




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



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






根据两个条件批量查询 mysql_sql语句_02




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



三、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。



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