1. 程式人生 > >Mybatis高階應用-巢狀查詢association和collection

Mybatis高階應用-巢狀查詢association和collection

Mybatis高階應用-巢狀查詢
1. 關聯-association
2. 集合-collection

  • 本文示例領域模型:
    訂單:訂單編號、顧客編號,總金額
    顧客:顧客編號、顧客姓名、顧客手機號
    貨物:貨物編號、貨物名稱、貨物單價
    訂單詳情:訂單、貨物列表、貨物總數量
  • 介面:OrderDetail getOrderDetail(String orderNo);
    獲取訂單詳情資訊,其中訂單詳情關聯了一個訂單(1:1),訂單詳情還關聯了一個貨物列表(1:n)

mybatis的實現:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.sf.shiva.oms.query.mapper.OrderMapper"> <resultMap id="OrderDetailResultMap" type="com.sf.shiva.oms.query.dto.OrderDetail"> <result property="totalGoodsCount"
column="totalGoodsCount" jdbcType="INTEGER" />
<association property="order" javaType="com.sf.shiva.oms.query.model.Order" column="order_no" select="selectOrder"> <id property="orderNo" column="order_no" jdbcType="INTEGER"/> <result property="customerNo"
column="customer_no" jdbcType="INTEGER"/>
<result property="amount" column="amount" jdbcType="DOUBLE"/> </association> <collection property="goodsList" ofType="com.sf.shiva.oms.query.model.Goods" select="selectGoods" column="order_no"> </collection> </resultMap> <select id="getOrderDetail" parameterType="java.lang.String" resultMap="OrderDetailResultMap"> select sum(rel.goods_quantity) as totalGoodsCount, order_no from order_goods_rel rel where rel.order_no=#{orderNo ,jdbcType=VARCHAR} </select> <select id="selectGoods" parameterType="java.lang.String" resultType="com.sf.shiva.oms.query.model.Goods" resultMap="GoodsResultMap"> select g.* from goods g, order_goods_rel rel where rel.order_no=#{orderNo} and rel.goods_no=g.goods_no </select> <resultMap id="GoodsResultMap" type="com.sf.shiva.oms.query.model.Goods"> <id column="goods_no" jdbcType="INTEGER" property="goodsNo" /> <result column="goods_name" jdbcType="VARCHAR" property="goodsName" /> <result column="goods_price" jdbcType="DOUBLE" property="goodsPrice" /> </resultMap> <select id="selectOrder" resultType="com.sf.shiva.oms.query.model.Order"> select order_no orderNo, customer_no customerNo, amount from t_order t where t.order_no = #{orderNo} </select> </mapper>
  • 需要注意的點:
    1. 主查詢語句的id是getOrderDetail,它的ResultMap就是對應了OrderDetail。ResultMap的id是OrderDetailResultMap,其包含了一個人result,一個association,一個collection。
    2. 特別注意ResultMap中的元素是有順序的。
      如果遇到報錯“元素型別為 “resultMap” 的內容必須匹配 “constructor?,id*,result*,association*,collection*,discriminator?)””。那麼就是元素的順序寫的不對,需要按照順序來寫,沒有的元素可以省略。
    3. result元素對應了OrderDetail中的totalGoodsCount,association對應了order,collection對應了goodsList。
    4. 在ResultMap中,凡column皆指資料庫欄位,凡property皆指Domain實體類的屬性。二者為對應關係,但是應理解區別,通常資料庫欄位為全小寫字母加分隔符,類的屬性為駝峰樣式。如:order_no,對應 orderNo。
    5. 特別的一點: 在association和collection的屬性中的column,對應的是主查詢語句中的查詢結果列,如果主查詢語句中沒有寫as別名,那麼就是資料庫列名。如果寫了別名,那麼這裡的column就要跟別名保持一致。比如,在上面的getOrderDetailsql中,寫了select sum(rel.goods_quantity) as totalGoodsCount, order_no from,那麼查詢的結果列就是totalGoodsCount和order_no,則關聯的association和collection中的column,就要寫order_no。如果查詢的sql中寫的是order_no as orderNo,那麼association和collection中的column就應該寫成orderNo。(測試時發現,寫成Order和orderNo都可以)。