天天看點

Mybaits結果集之集合,Javabean中嵌套List的解決方案

有類似這樣的場景,我作為一個寫作者來說,我寫了很多篇文章,如果把我抽象成一個對象,那麼該如何通過Mybatis 擷取到我和我寫的文章呢?這種情況下,使用Mybatis結果集的集合就可以滿足需求。

在我的實際項目中,需要是要通過市場market擷取對應的商品。

商品和市場的Javabean大緻如下:

Markets.java
public class Markets extends DataEntity<Markets> {
    private Integer id;
    private String marketname;
    private String marketcode;
    private Integer market_weight;
    private List<Goods> goods;
    ......      

Goods.java

public class Goods  extends DataEntity<Goods> {
    private Long id;
    private Integer market_id;
    private String serial_num;
    private String name;      

在mybatis-config.xml中定義其别名如下:

<typeAlias alias='Markets' type='com.cmower.database.entity.Markets' />

<typeAlias alias='Goods' type='com.cmower.database.entity.Goods' />

在MarketMapper.xml中定義一個resultMap,其内容大緻如下:

<resultMap type="Markets" id="BaseGoodMarketResultMap">
    <id column="id" property="id" />
    <result column="marketcode" property="marketcode" />
    <result column="marketname" property="marketname" />
    <result column="market_weight" property="market_weight" />
    <result column="market_type" property="market_type" />
    <!-- 這句特别重要,它的作用就是将selectGoodsForMarket取出的結果集映射到Markets這個Javabean中的goods屬性 -->
    <collection property="goods" column="id" ofType="Goods" select="selectGoodsForMarket"/>
</resultMap>

<!-- 其中market_id=#{id}中的id為<collection>傳遞的column屬性值 -->
<select id="selectGoodsForMarket" resultType="Goods">
  SELECT 
    g.id,
    g.name,
    g.price_str,
    g.goods_thumb 
FROM 
    ym_goods g 
where g.del_flag = 0 and g.market_id=#{id}
order by g.id DESC
limit 6
</select>

<select id="selectGoodMakets" resultMap="BaseGoodMarketResultMap">
    select 
        m.*
    from 
        market m 
    where 
        m.del_flag = 0 and m.market_type = 0
</select>      

以上内容就是Mybaits結果集之集合的一種寫法,在調用selectGoodMakets進行查詢時,傳回的結果集為BaseGoodMarketResultMap,在BaseGoodMarketResultMap中,定義了<collection property="goods" column="id" ofType="Goods" select="selectGoodsForMarket"/>,它表明要從另外一個結果集selectGoodsForMarket取出的一個傳回Goods集合list到Markets這個Javabean中的goods屬性中。

其SQL執行順序如下圖:

Mybaits結果集之集合,Javabean中嵌套List的解決方案

也就是說先執行了selectGoodMakets,然後再依次執行了三次selectGoodsForMarket。

這達到了我們期望的結果,但如果selectGoodMakets結果集有很多的話,selectGoodsForMarket就會執行很多次,有沒有更好的方法,隻執行一條SQL就擷取到期望的結果集呢?

有到是有,但結果子結果無法進行limit,這并不是我想要的結果(Stack Overflow上也沒有找到想要的答案),不過,就當是學習吧。

<resultMap type="Markets" id="BaseGoodMarketResultMap1">
    <id column="id" property="id" />
    <result column="marketcode" property="marketcode" />
    <result column="marketname" property="marketname" />
    <result column="market_weight" property="market_weight" />
    <result column="market_type" property="market_type" />

    <collection property="goods" ofType="Goods">
        <id column="good_id" property="id" />
        <result column="name" property="name" />
        <result column="price_str" property="price_str" />
        <result column="is_promote" property="is_promote" />
        <result column="issue_price" property="issue_price" />
        <result column="max_point" property="max_point" />
        <result column="back_point" property="back_point" />
        <result column="can_use_point" property="can_use_point" />
        <result column="goods_thumb" property="goods_thumb" />
    </collection>
</resultMap>

<select id="selectGoodMaketsOneSql" resultMap="BaseGoodMarketResultMap1">
    select
        g.id as good_id,
        g.name,
        g.price_str,
        g.is_promote,
        g.issue_price,
        g.max_point,
        g.back_point,
        g.can_use_point,
        g.goods_thumb,
        m.*
    from 
        market m 
        left join ym_goods g on m.id=g.market_id and g.del_flag = 0 and g.status =3 and g.is_onsale=1
    where 
        m.del_flag = 0 and m.market_type = 0
</select>