mybatis使用的奇技淫巧

合併多行查詢的結果

業務需求

商家能夠根據商品類目分類,每位商家能夠有多個商品類目,商品類目又跟運營類目有一種關聯規則。此處暫且不說運營類目。根據業務,商家信息是一張表,商家與商品類目有一張關聯表,商品類目有一張表,權且使用三張表。前端

其餘不相干字段不展現
  • 商家表(user)
uid username mobile
1 張三 12345678901
2 李四 12345600002
  • 商品類目表(item_category)
icid name status parentid
1 服裝 0 0
2 茶具 0 0
3 食品 0 0
  • 商家與商品類目(user_item_cate_rel)
uid icid
1 1
1 2
2 1
2 3

若是咱們須要在前端頁面展現每一個商家的商品類目,那麼咱們返回的結果中就須要每條商家數據中包含所屬商品的類目。實現方式有不少種:1.一條sql語句能夠實現,使用group_concat函數並根據uid分組2.先查詢商家信息,再根據商家uid查詢user_item_cate_rel和item_category表,再將結果在model中組合3.用mybatis的resultMap。此處只看1和3的實現方式。java

  • 展現需求:
# 商家ID 商家名 手機號碼 商品類目 操做
1 1 張三 12345678901 服裝,茶具 刪除 修改
2 2 李四 12345600002 服裝,食品 刪除 修改

group_caoncat實現

SELECT u.*,group_concat(ic.name) categories FROM user 
LEFT JOIN user_item_cate_rel uicr
ON u.uid = uicr.uid
LEFT JOIN item_category ic
ON uicr.icid = ic.icid
WHERE ... # 查詢條件
GROUP BY u.uid

大概就這樣,能夠把類目直接返回給前端,毫無疑問,這個實現是最快的。可是,當數據量大的時候,而且是查詢列表的時候,全表掃描,就會出現慢查詢。sql

巧妙使用Mybatis resultMap

建立User和Category POJO。User除了user表的字段做爲屬性外,外加一個private List<Category> categories屬性。Category的字段分別爲:icidname數據庫

mapper的xml中:數組

  • 先定義一個id爲user的resultMap:
<resultMap id="user" type="User" autoMapping="true">
    <collection property="categories" ofType="Category" select="getCategory" column="uid" javaType="ArrayList">
        <id property="icid" column="icid"/>
        <result property="name" column="name"/>
    </collection>
</resultMap>
  • 實現select屬性對應方法:此處select的id爲上面id爲user的resultMap中collection的select元素,參數#{uid}爲column元素指定的字段。
<select id="getCategory" resultType="Category">
    SELECT uicr.icid,ic.name FROM user_item_cate_rel uicr
    LEFT JOIN item_category ic
    ON uicr.icid = ic.icid
    WHERE uicr.uid = #{uid}
</select>
  • 獲取指定條數的數據:mybatis能夠根據傳入的參數組裝sql語句。
<select id="getUsers" parameterType="UserSearch" resultMap="user">
    SELECT u.* FROM user u LEFT JOIN user_item_cate_rel uicr 
    ON u.uid = uicr.uid
    WHERE 1=1
    <if test="uid != null"> AND u.uid = #{uid} </if>
    <if test="username != null"> AND u.username LIKE concat('%',#{username}, '%')</if>
    <if test="mobile != null"> AND u.mobile = #{mobile}</if>
    <if test="icid != null"> AND uicr.icid = #{icid}</if>
    ..... // 各類查詢條件
    LIMIT #{page},#{offset}
</select>

上面查詢中,UserSearch是查詢條件POJO,能夠根據須要自定義過濾那些字段。其中有一個屬性是icid,就是根據傳入的一個商品類目查詢商家信息。好比,要查詢icid=1的商家,那麼咱們返回的數據不單單是icid=1的,還應該是icid=1商家的其餘icid信息。mybatis

那麼查詢結果應該爲:app

[
    {
        "uid": 1,
        "username": "張三",
        "mobile": "12345678901",
        "categories": [
            {
                "icid": 1,
                "name": "服裝"
            },
            {
                "icid": 2,
                "name": "茶具"
            }
        ]
    },
    {
        "uid": 2,
        "username": "李四",
        "mobile": "12345600002",
        "categories": [
            {
                "icid": 1,
                "name": "服裝"
            },
            {
                "icid": 3,
                "name": "服裝"
            }
        ]
    }
]
此處須要注意一點,resultMap的select元素調用getCategory方法時,自動映射的屬性名和列名應該保持一致,或者列表必須是數據庫表中的字段名,而不是別名。
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息