【需求】java
查詢訂單以及訂單明細的信息。sql
肯定主查詢表:訂單表orders數據庫
肯定關聯查詢表:訂單明細表 orderdetailapache
在一對一查詢的基礎上添加訂單明細表關聯便可。session
【分析】mybatis
使用resultMap將上面的查詢結果映射到pojo中,訂單信息有重複。app
要求:對orders映射不能出現重複記錄ui
在orders.java類中添加List<orderDetail> orderDetails屬性。spa
最終會將訂單信息映射到orders中,訂單所對應的訂單明細映射到orders中的orderDetails屬性中。以下所示:debug
映射成的orders記錄爲兩條(orders信息不能重複)
每一個orders中的orderDetails屬性存儲了該訂單所對應的訂單明細。
【工程截圖】
【User.java】
package cn.higgin.mybatis.po; import java.util.Date; public class User { //屬性名和數據庫表的字段對應 private int id; private String username; private String sex; private Date birthday; private String address; //set/get方法忽略..... }
【Orderdetail.java】
package cn.higgin.mybatis.po; public class Orderdetail { private Integer id; private Integer ordersId; private Integer itemsId; private Integer itemsNum; //get/set方法忽略...... }
【Orders.java】
package cn.higgin.mybatis.po; import java.util.Date; import java.util.List; public class Orders { private Integer id; private Integer userId; private String number; private Date createtime; private String note; //引入用戶信息 private User user; //引入訂單明細(和上面的用戶信息不一樣,一個是一對一,一個是一對多) private List<Orderdetail> orderdetails; //注意是orderdetails,一個有's',一個有's' //忽略set/get方法...... }
【OrdersMapperCustom.java】
package cn.higgin.mybatis.mapper; import java.util.List; import cn.higgin.mybatis.po.Orders; public interface OrdersMapperCustom { //查詢訂單(關聯用戶)及訂單明細 public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception; }
【OrdersMapperCustomer.xml】
<?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="cn.higgin.mybatis.mapper.OrdersMapperCustom"> <!-- 訂單查詢關聯用戶的resultMap 將整個查詢的結果映射到cn.higgin.mybatis.po.Orders中 --> <resultMap type="cn.higgin.mybatis.po.Orders" id="OrdersUserResultMap"> <!-- 配置訂單的映射信息 --> <!-- id:指定查詢列中的惟一標識,訂單信息中的惟一標識,如有多個列組成惟一標識,需配置多個id column: 訂單信息的惟一標識列 property: 訂單信息的惟一標識列所映射到的 Orders的對應的屬性 --> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number" /> <result column="createtime" property="createtime"/> <result column="note" property="note" /> <!-- 配置映射的關聯的用戶信息 --> <!-- association:用於映射關聯查詢單個對象的信息 property:要將關聯查詢的用戶信息映射到Orders中的對應屬性 --> <association property="user" javaType="cn.higgin.mybatis.po.User"> <!-- id:關聯查詢用戶的惟一標識 column:指定惟一標識用戶信息的列 javaType:映射到user的對應屬性 --> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> </association> </resultMap> <!-- 訂單及訂單明細的resultType 使用extends繼承OrdersUserResultMap中的信息,無需在其中配置訂單和用戶的信息 --> <resultMap type="cn.higgin.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"> <!-- 1.訂單信息(從繼承的OrdersUserResultMap中獲取) --> <!-- 2.用戶信息(從繼承的OrdersUserResultMap中獲取) --> <!-- 訂單明細信息 一個訂單關聯查詢出了多條明細,要使用collection進行映射 collection:對關聯查詢到多條記錄映射到集合對象中 property: 將關聯查詢到多條記錄映射到cn.higgin.mybatis.po.Orders的對應屬性 ofType: 指定映射到list集合屬性中pojo的類型,在[Orders.java]中的 private List<Orderdetail> orderdetails; --> <collection property="orderdetails" ofType="cn.higgin.mybatis.po.Orderdetail"> <!-- id:訂單明細惟一標識 property:要將訂單明細的惟一標識映射到cn.higgin.mybatis.po.Orderdetail的對應屬性 --> <id column="orderdetail_id" property="id"/> <result column="items_id" property="id"/> <result column="items_num" property="itemsNum"/> <result column="orders_id" property="ordersId"/> </collection> </resultMap> <!-- 查詢訂單關聯查詢用戶信息,使用resultMap --> <select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap"> SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id FROM orders,USER,orderdetail WHERE orders.user_id=user.id AND orderdetail.orders_id=orders.id </select> </mapper>
【SplMapConfig.xml 和 db.properties 與前一篇博文相同】
【OrdersMapperCustomTest.java】
package cn.higgin.mybatis.mapper; import java.io.InputStream; import java.util.List; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import cn.higgin.mybatis.po.Orders; public class OrdersMapperCustomTest { private SqlSessionFactory sqlSessionFactory; // 此方法是在執行testFindUserById以前執行 @Before public void setUp() throws Exception { // 建立sqlSessionFactory // mybatis配置文件 String resource = "SqlMapConfig.xml"; // 獲得配置文件流 InputStream inputStream = Resources.getResourceAsStream(resource); // 建立會話工廠,傳入mybatis的配置文件信息 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testFindOrdersUser() throws Exception { SqlSession sqlSession=sqlSessionFactory.openSession(); //建立代理對象 OrdersMapperCustom ordersMapperCustom=sqlSession.getMapper(OrdersMapperCustom.class); //調用mapper的方法 List<Orders> list=ordersMapperCustom.findOrdersAndOrderDetailResultMap(); System.out.println(list.size()); sqlSession.close(); } }
【debug運行結果】
可見只有兩條記錄:
再查看一下具體內容:
注意:重複的數據被合併,不重複的數據在集合中,下圖做對比:
【小結】
mybatis使用resultMap的collection對關聯查詢的多條記錄映射映射到一個list集合屬性中(private List<Orderdetail> orderdetails;)。
使用resultType也能夠實現:
將訂單明細映射到orders中的orderdetails中,須要本身處理,使用雙重循環遍歷,去掉重複記錄,將訂單明細放在orderdetails中。