mybatis 動態sql語句實現多條件查詢(foreach的使用)
阿新 • • 發佈:2019-01-09
一、前言
現有一個需求:實現多條件、不確定條件的搜尋功能。
類似於淘寶網進行搜尋商品的時候,可以在搜尋框進行模糊搜尋,同時可以進行條件篩選,例如想買一隻 口紅? 的時候,可以在搜尋框內輸入“口紅”,還可以選擇品牌、是否包郵、價格區間等等。。最後搜尋出來的結果是滿足所有篩選的條件的。
這裡我認為的難點就是:這些條件你不確定需不需要,你不確定選了幾個,所以說這些都是動態的。
我總結了一句話來進行概括:同類型條件取並集,不同型別條件取交集。
二、前臺介面(瞭解需求)
頁面預設載入全部資料當有搜尋條件後,取滿足所有條件的資料:試題內容中包括關鍵字”程式“、試題型別為”判斷題“、所屬知識點為”關係運算符、物件的概念“。 這裡前臺使用了easyui框架、下拉框多選技術、easyUI分頁技術參考我的這兩篇博文:
在本頁面可以看出,在所有試卷中,可以通過關鍵字搜尋試題內容,通過複選下拉框篩選”試題型別“、”所屬知識點“這兩種條件。
三、mybatis sql語句
這個sql涉及到了三張表的查詢,其中還包括巢狀查詢。寫這個之前真的沒想到自己能寫出這麼複雜的sql語句。 暫時還沒考察其健壯性,現在就是把功能都實現了。 把sql語句貼出來:where前面的不用看,主要看<where>裡面有三個<if>。這就是”不同型別條件取交集“,所以這裡用到了 <where> <if> </if> <if> </if> <if> </if> </where>這樣的結構來對條件進行篩選。 第一個<if>實現了關鍵字的模糊搜尋。 第二個<if>由於涉及到了另一張表的條件查詢,所以用到了巢狀查詢。 在前臺,下拉框的條件值可以為多個。所以前臺會給後臺傳一個list,其中 kp_title 是用來存放第一個下拉框的值的一個Map。 在這個巢狀語句裡面用到了<foreach></foreach>,可以對map、list、array這三種資料型別進行遍歷。在本栗子中,<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>
collection裡面的kp_title為map的key值。item是用來遍歷map的value值的一個別名。 第三個<if>與第二個的內容相似,只不過是又多關聯查詢了第三張表。<foreach collection="kp_title" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach>