1.商品訂單數據模型
1.1數據模型分析思路
(1)每張表記錄的數據內容
分模塊對每張表記錄的內容進行熟悉,相當于你學習系統需求(功能)的過程。
(2)每張表重要的字段設置
非空字段、外鍵字段
(3)數據庫級別表與表之間的關系
外鍵關系
(4)表與表之間的業務關系
在分析表與表之間的業務關系時,一定要建立在某個業務意義基礎上去分析。
1.2屬性模型分析
2.一對一查詢
2.1需求
查詢訂單信息,關聯查詢下單用戶信息。
2.2方法一:resultType
2.2.1sql語句
確定查詢的主表:訂單表
確定查詢的關聯表:用戶表
關聯查詢使用內鏈接?還是外鏈接?
由于orders表中有一個外鍵(user_id),通過外鍵關聯查詢用戶表只能查詢出一條記錄,可使用內鏈接。
SELECT orders.*, USER.username, USER.sex, USER.address FROM orders, USER WHERE orders.user_id = user.id
2.2.2創建pojo
將上邊sql查詢的結果映射到pojo中,pojo中必須包括所有查詢列名。
原始Orders.java不能映射全部字段,需要新創建pojo。
創建一個pojo繼承包括查詢字段較多的pojo類。
2.2.3mapper.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"> <!--namespace命名空間,作用就是對sql進行分類化的管理,理解為sql隔離 注意:使用mapper代理開發時,namespace有特殊作用,namespace等于mapper接口地址 --> <mapper namespace="joanna.yan.mybatis.mapper.OrdersCustomMapper"> <!--查詢訂單,關聯查詢用戶信息 --> <select id="findOrdersUser" resultType="joanna.yan.mybatis.entity.OrdersCustom"> SELECT orders.*, USER.username, USER.sex, USER.address FROM orders, USER WHERE orders.user_id = user.id </select> </mapper>
2.2.4mapper.java
public interface OrdersCustomMapper { //查詢訂單,關聯查詢用戶信息 public List<OrdersCustom> findOrdersUser() throws Exception; }
2.2.5測試程序
@Test public void findOrdersUserTest() throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); OrdersCustomMapper ordersCustomMapper=sqlSession.getMapper(OrdersCustomMapper.class); List<OrdersCustom> list=ordersCustomMapper.findOrdersUser(); System.out.println(list); sqlSession.close(); }
2.3方法二:resultMap
2.3.1sql語句
同resultType實現的sql
2.3.2使用resultMap映射的思路
使用resultMap將查詢結果中的訂單信息映射到Orders對象中,在Orders類中添加User屬性,將關聯查詢出來的用戶信息映射到orders對象中的user屬性中。
2.3.3需要orders類中添加user屬性
2.3.4mapper.xml
2.3.4.1定義resultMap
<!--訂單關聯查詢用戶的resultMap 將整個查詢的結果映射到oanna.yan.mybatis.entity.Orders中 --> <resultMap type="joanna.yan.mybatis.entity.Orders" id="OrdersUserResultMap"> <!-- 1.配置映射的訂單信息 --> <!-- 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"/> <!-- 2.配置映射的關聯的用戶信息 --> <!-- association:用于映射關聯查詢單個對象的信息 property:要將關聯查詢的用戶信息映射到Orders類中的哪個屬性 --> <association property="user" javaType="joanna.yan.mybatis.entity.User"> <!-- 關聯查詢用戶的唯一標識 column:指定唯一標識用戶信息的列 property:映射到user的哪個屬性 --> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="sex"/> </association> </resultMap>
2.3.4.2定義statement定義
<!--查詢訂單,關聯查詢用戶信息,使用ResultMap --> <select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap"> SELECT orders.*, USER.username, USER.sex, USER.address FROM orders, USER WHERE orders.user_id = user.id </select>
2.3.4.3mapper.java
public interface OrdersCustomMapper { //查詢訂單,關聯查詢用戶信息,使用resultMap public List<Orders> findOrdersUserResultMap() throws Exception; }
2.3.4.4測試程序
@Test public void findOrdersUserResultMapTest() throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); OrdersCustomMapper ordersCustomMapper=sqlSession.getMapper(OrdersCustomMapper.class); List<Orders> list=ordersCustomMapper.findOrdersUserResultMap(); System.out.println(list); sqlSession.close(); }
2.4 resultType和resultMap實現一對一查詢小結
實現一對一查詢:
resultType:使用resultType實現較為簡單,如果pojo中沒有包括查詢出來的列名,需要增加列名對應的屬性,即可完成映射。
如果沒有查詢結果的特殊要求,建議使用resultType。
resultMap:需要單獨定義resultMap,實現有點麻煩,如果對查詢結果又特殊的要求,使用resultMap可以完成將關聯查詢映射pojo的屬性中。
resultMap可以實現延遲加載,resultType無法實現延遲加載。
3.一對多查詢
3.1需求
查詢訂單及訂單明細的信息
3.2sql語句
確定主查詢表:訂單表
確定關聯查詢表:訂單明細表
在一對一查詢基礎上添加訂單明細表關聯即可。
SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, 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
3.3分析
使用resultType將上邊的查詢結果映射到pojo中,訂單信息的就會重復。
要求:
對orders的映射不能出現重復記錄。
解決:
在Orders.java類中添加List<OrderDetail> orderDetails屬性。
最終會將訂單信息映射到Orders中,訂單所對應的訂單明細映射到orders中的orderDetails屬性中。
映射成的orders記錄數為兩條(orders信息不重復)
每個orders中的orderDetails屬性存儲了該訂單所對應的訂單明細。
3.4在Orders類中添加list訂單明細屬性
3.5定義resultMap
<!--訂單及訂單明細的resultMap 使用extends繼承,就不需要再配置訂單信息和用戶信息的映射了 --> <resultMap type="joanna.yan.mybatis.entity.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"> <!-- 1.配置映射的訂單信息 --> <!-- 2.配置映射的關聯的用戶信息 --> <!-- 使用extends繼承,就不需要再配置訂單信息和用戶信息的映射了 --> <!-- 3.配置映射的訂單明細信息 --> <!-- 訂單明細信息 一個訂單關聯查詢出了多條明細,要使用collection進行映射 collection:對關聯查詢到的多條記錄映射到集合對象中 property:將關聯查詢到多條記錄映射到joanna.yan.mybatis.entity.Orders中的哪個屬性 ofType:指定映射到list集合屬性中pojo的類型 --> <collection property="orderdetails" ofType="joanna.yan.mybatis.entity.Orderdetail"> <!-- id:訂單明細的唯一標識 property:要講訂單明細的唯一標識映射到joanna.yan.mybatis.entity.Orderdetail的哪個屬性 --> <id column="orderdetail_id" property="id"/> <result column="items_id" property="itemsId"/> <result column="items_num" property="itemsNum"/> <result column="orders_id" property="ordersId"/> </collection> </resultMap>
3.6mapper.xml
<!-- 查詢訂單,關聯查詢用戶及訂單明細,使用resultMap --> <select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap"> SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, 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>
3.7mapper.java
public interface OrdersCustomMapper { //查詢訂單,關聯查詢用戶信息 public List<OrdersCustom> findOrdersUser() throws Exception; //查詢訂單,關聯查詢用戶信息,使用resultMap public List<Orders> findOrdersUserResultMap() throws Exception; //查詢訂單(關聯用戶)及訂單明細 public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception; }
3.8測試程序
@Test public void findOrdersAndOrderDetailResultMapTest() throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); OrdersCustomMapper ordersCustomMapper=sqlSession.getMapper(OrdersCustomMapper.class); List<Orders> list=ordersCustomMapper.findOrdersAndOrderDetailResultMap(); System.out.println(list); sqlSession.close(); }
3.9小結
mybatis使用resultMap的collection對關聯查詢的多條記錄映射到有個list集合屬性中。
使用resultType實現:
將訂單明細映射到orders中的orderdetails中,需要自己處理,使用雙重循環遍歷,去掉重復記錄,將訂單明細放在ordertails中。
4.多對多查詢
4.1需求
查詢用戶及用戶購買的商品信息。
4.2sql語句
查詢主表:用戶表
關聯表:由于用戶和商品沒有直接關聯,通過訂單和訂單明細進行關聯,所有關聯表:orders、orderdetail、items。
SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id, items.name items_name, items.detail items_detail, items.price items_price FROM orders, USER, orderdetail, items WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id
4.3映射思路
將用戶信息映射到user中。
在User類中添加訂單列表屬性List<Orders> orderslist,將用戶創建的訂單映射到orderslist;
在Orders中田間訂單明細列表屬性List<OrderDetail> orderdetails,將訂單的明細映射到orderdetails;
在OrderDetail中添加Items屬性,將訂單明細所對應的商品映射到Items。
4.4 mapper.xml
<select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap"> SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id, items.name items_name, items.detail items_detail, items.price items_price FROM orders, USER, orderdetail, items WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id </select>
4.5定義resultMap
<!-- 查詢用戶及購買商品 --> <resultMap type="joanna.yan.mybatis.entity.User" id="UserAndItemsResultMap"> <!-- 1.用戶信息 --> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> <!-- 2.訂單信息 --> <!-- 一個用戶對應多個訂單,使用collection映射 --> <collection property="ordersList" ofType="joanna.yan.mybatis.entity.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"/> <!-- 3.訂單明細 --> <!-- 一個訂單包括多個明細 --> <collection property="orderdetails" ofType="joanna.yan.mybatis.entity.Orderdetail"> <id column="orderdetail_id" property="id"/> <result column="items_id" property="itemsId"/> <result column="items_num" property="itemsNum"/> <result column="orders_id" property="ordersId"/> <!-- 4.商品信息 --> <!-- 一個訂單明細對應一個商品 --> <association property="items" javaType="joanna.yan.mybatis.entity.Items"> <id column="items_id" property="id"/> <result column="items_name" property="name"/> <result column="items_detail" property="detail"/> <result column="items_price" property="price"/> </association> </collection> </collection> </resultMap>
4.6mapper.java
public interface OrdersCustomMapper { //查詢訂單,關聯查詢用戶信息 public List<OrdersCustom> findOrdersUser() throws Exception; //查詢訂單,關聯查詢用戶信息,使用resultMap public List<Orders> findOrdersUserResultMap() throws Exception; //查詢訂單(關聯用戶)及訂單明細 public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception; //查詢用戶購買商品信息 public List<User> findUserAndItemsResultMap() throws Exception; }
4.7測試程序
@Test public void findUserAndItemsResultMapTest() throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); OrdersCustomMapper ordersCustomMapper=sqlSession.getMapper(OrdersCustomMapper.class); List<User> list=ordersCustomMapper.findUserAndItemsResultMap(); System.out.println(list); sqlSession.close(); }
4.8多對多查詢總結
將查詢用戶購買的商品信息明細清單(用戶名、用戶地址、購買商品名稱、購買商品時間、購買商品數量)
針對上面的需求就使用resultType將查詢到的記錄映射到一個擴展的pojo中,很簡單實現明細清單的功能。
一對多是多對多的特例,如下需求:
查詢用戶購買的商品信息,用戶和商品的關系是多對多關系。
需求1:
查詢字段:用戶賬號、用戶名稱、用戶性別、商品名稱、商品價格(最常見)
企業開發中常見明細列表,用戶購買商品明細列表,
使用resultType將上邊查詢列映射到pojo輸出。
需求2:
查詢字段:用戶賬號、用戶名稱、購買商品數量、商品明細(鼠標移上顯示明細)
使用resultMap將用戶購買的商品明細列表映射到user對象中。
總結:
使用resultMap是針對那些對查詢結果映射有特殊要求的功能,比如特殊要求映射成list中包含多個list。
5.resultMap總結
resultType:
作用:將查詢結果按照sql列名pojo屬性一致性映射到pojo中。
場合:
常見一些明細記錄的展示,比如用戶購買商品明細,將關聯查詢信息全部展示在頁面時,此時可直接使用resultType將每一條記錄映射到pojo中,在前端頁面遍歷list(list中是pojo)即可。
resultMap:
使用association和collection完成一對一和一對多高級映射(對結果又特殊的映射要求)。
association:
作用:將關聯查詢信息映射到一個pojo對象中。
場合:
為了方便查詢關聯信息可以使用association將關聯訂單信息映射為用戶對象的pojo屬性中,比如:查詢訂單及關聯用戶信息。
使用resultType無法將查詢結果映射到pojo對象的pojo屬性中,根據對結果集查詢遍歷的需要選擇使用resultType還是resultMap。
collection:
作用:將關聯查詢信息映射到一個list集合中。
場合:為了方便擦還行遍歷關聯信息可以使用collection將關聯信息映射到list集合中,比如:查詢用戶權限范圍模塊及模塊下的菜單,可使用collection將模塊映射到模塊list中,將菜單列表映射到模塊對象的菜單list屬性中,這樣做冊目的也是方便對查詢結果集進行遍歷查詢。
如果使用resultType無法將查詢結果映射到list集合中。
文章列表