MyBatis(7)高級查詢


本次全部學習內容MyBatisLearning

高級查詢:
 
對於整體的工程是時候增加一點文件了:

具體用到那個類再去說明類的內容

 
一對一查詢:
1.resultType進行實現:
執行的sql語句:
查詢的主表:訂單表
查詢的關聯表:用戶表
orders表有一個外鍵
 select orders.*,user.username,user.sex,user.address  from orders ,user where orders.user_id = user.id;
 
 ordersCustomer.java
public class OrdersCustom extends Orders{
     
     //添加用戶屬性
     /*USER.username,
       USER.sex,
       USER.address */
     private String username;
     private String sex;
     private String address;
.......
}

 orders.java

public class Orders {
    private Integer id;
    private Integer userId;
    private String number;
    private Date createtime;
    private String note;
   
    //用戶信息
    private User user;
............
}

 首先在本次的xml文件中,OrderMapperCustomer.xml文件中

<!-- 一對一查詢 -->
<!-- resultType -->
<select id="findOrderUsers" resultType="com.MrChengs.po.OrdersCustom">
select orders.*,user.username,user.sex,user.address 
from orders ,user where orders.user_id = user.id;
</select>

 在OrderMapperCustomerj接口類中

     //resultType
     //查詢訂單關聯用戶信息
     public List<OrdersCustom> findOrderUsers() throws Exception;

 實現類:

//resultType
     //實現用戶訂單關聯信息
     @Test
     public void testfindOrderUsers() throws Exception {
           SqlSession sqlSession = getSqlSessionFactory().openSession();
           
           //代理對象
           OrderMapperCustomer mapper = sqlSession.getMapper(OrderMapperCustomer.class);
           
           //測試findOrderUsers
           List<OrdersCustom> orders = mapper.findOrderUsers();
           
           for(OrdersCustom o : orders){
                System.out.println(o);
           }
           
           sqlSession.close();
     }

 結果:

DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3ecd23d9]
DEBUG [main] - ==>  Preparing: select orders.*,user.username,user.sex,user.address from orders ,user where orders.user_id = user.id;
DEBUG [main] - ==> Parameters:
DEBUG [main] - <==      Total: 3
OrdersCustom [username=王五, sex=2, address=null, getUsername()=王五, getSex()=2, getAddress()=null,......
OrdersCustom [username=王五, sex=2, address=null, getUsername()=王五, getSex()=2, getAddress()=null,.....
OrdersCustom [username=張三, sex=1, address=北京市, getUsername()=張三, getSex()=1, getAddress()=北京市,.....

 

對於resultMap來實現
在xml文件中:
<!-- resultMap -->
<!-- 映射到Orders這個表中 -->
<!-- Orders需要添加user的信息 -->
<resultMap type="com.MrChengs.po.Orders" id="odersandUser">
     <!-- 訂單信息的唯一 標識 -->
     <!-- id;配置查詢列的唯一標識,訂單信息中的唯一標識,如果有多個則配置多個id屬性 -->
     <!-- result:把訂單列中的普通列進行映射 -->
     <!-- column:數據庫查詢的列,property:映射表中的屬性 -->
     <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:用於映射關聯關系的對象信息 -->
     <!-- id:關聯用戶的唯一標識 -->
     <!--  column:指定唯一標識的用戶信息列,數據庫的查詢列-->
     <!-- javaType:映射user的那個屬性 -->
     
     <association property="user" javaType="com.MrChengs.po.User">
     
           <id column="user_id" property="id"/>
           <result column="username" property="username"/>
           <result column="sex" property="sex"/>
           <result column="address" property="address"/>
     </association>
</resultMap>
<select id="findOrderUserByMap" resultMap="odersandUser">
select orders.*,user.username,user.sex,user.address 
from orders ,user where orders.user_id = user.id;
</select>

 接口類:

    //resultMap
     //查詢訂單關聯用戶信息
     public List<Orders> findOrderUserByMap() throws Exception;

 測試類:

//resultType
           //實現用戶訂單關聯信息
           @Test
           public void testfindOrderUserByMap() throws Exception {
                SqlSession sqlSession = getSqlSessionFactory().openSession();
                
                //代理對象
                OrderMapperCustomer mapper = sqlSession.getMapper(OrderMapperCustomer.class);
                
                //測試findOrderUsers
                List<Orders> orders = mapper.findOrderUserByMap();
                
                for(Orders order : orders){
                     System.out.println(order);
                }
                
                sqlSession.close();
           }

 結果:

DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3ecd23d9]
DEBUG [main] - ==>  Preparing: select orders.*,user.username,user.sex,user.address from orders ,user where orders.user_id = user.id;
DEBUG [main] - ==> Parameters:
DEBUG [main] - <==      Total: 3
Orders [id=3, userId=1, number=1000010, createtime=Wed Feb 04 13:22:35 CST 2015, note=null, user=User [id=1, username=王五, birthday=null, sex=2, address=null], orderdetails=null]
Orders [id=4, userId=1, number=1000011, createtime=Tue Feb 03 13:22:41 CST 2015, note=null, user=User [id=1, username=王五, birthday=null, sex=2, address=null], orderdetails=null]
Orders [id=5, userId=10, number=1000012, createtime=Thu Feb 12 16:13:23 CST 2015, note=null, user=User [id=10, username=張三, birthday=null, sex=1, address=北京市], orderdetails=null]

 

resultType and resultMap:
resultType:使用resultType實現較為簡單,如果pojo中沒有包括查詢出來的列名,需要增加列名對應的屬性,即可完成映射。
如果沒有查詢結果的特殊要求建議使用resultType。
resultMap:需要單獨定義resultMap,實現有點麻煩,如果對查詢結果有特殊的要求,使用resultMap可以完成將關聯查詢映射pojo的屬性中。
resultMap可以實現延遲加載,resultType無法實現延遲加載。
 
 
 
 
 
一對多的查詢:
 
確定主查詢表:訂單表
確定關聯查詢表:訂單明細表
在一對一查詢基礎上添加訂單明細表關聯即可。
 
要求:
    對orders映射不能出現重復記錄。
    在orders.java類中添加List<orderDetail> orderDetails屬性。
    最終會將訂單信息映射到orders中,訂單所對應的訂單明細映射到orders中的orderDetails屬性中。
 
SELECT
  orders.*,
  USER.username,
  USER.sex,
  USER.address,
//防止id段重復
 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

 首先在接口類:

     //查詢訂單及訂單明細
     //一對多
     public List<Orders> findOrderUserDetailResultMap() throws Exception;

 xml文件中;

 
<!-- orders & User在之前寫過,此時可以不在累贅,使用繼承 -->
<resultMap type="com.MrChengs.po.Orders" id="OrderUserDetailResultMap" extends="odersandUser">
     <!-- orders --> 
     <!-- User -->
     <!-- 此時使用了繼承 -->
     <!-- 訂單明細 -->
     <!-- 一個訂單對應多條明細 -->
     <!-- property:映射到Orders的那個屬性 -->
     <!-- ofType:指映射集合pojo的類型 -->
     
     <collection property="orderdetails" ofType="com.MrChengs.po.Orderdetail">
           
           <!-- id:訂單明細的唯一標識 -->
           <!-- property:將訂單映射到訂單唯一標識的 com.MrChengs.po.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>

<select id="findOrderUserDetailResultMap" resultMap="OrderUserDetailResultMap">
            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>

 orders.java類中添加屬性:

//訂單明細
    private List<Orderdetail> orderdetails;

 測試類中:

//實現用戶訂單關聯信息
           //多對多
           @Test
           public void testfindOrderUserByMap() throws Exception {
                SqlSession sqlSession = getSqlSessionFactory().openSession();
                
                //代理對象
                OrderMapperCustomer mapper = sqlSession.getMapper(OrderMapperCustomer.class);
                
                //測試findOrderUsers
                List<Orders> orders = mapper.findOrderUserDetailResultMap();
                
                for(Orders order : orders){
                     System.out.println(order);
                }
                
                sqlSession.close();
           }

 

 實現的結果:
 
DEBUG [main] - ==>  Preparing: 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
DEBUG [main] - ==> Parameters:
DEBUG [main] - <==      Total: 4

Orders [id=3, userId=1, number=1000010, createtime=Wed Feb 04 13:22:35 CST 2015, note=null, user=User [id=1, username=王五, birthday=null, sex=2, address=null], orderdetails=[Orderdetail [id=1, ordersId=3, itemsId=1, itemsNum=1], Orderdetail [id=2, ordersId=3, itemsId=2, itemsNum=3]]]

Orders [id=4, userId=1, number=1000011, createtime=Tue Feb 03 13:22:41 CST 2015, note=null, user=User [id=1, username=王五, birthday=null, sex=2, address=null], orderdetails=[Orderdetail [id=3, ordersId=4, itemsId=3, itemsNum=4], Orderdetail [id=4, ordersId=4, itemsId=2, itemsNum=3]]]

 

 
 
 
多對多的查詢:
 
查詢用戶以及用戶所購買的商品信息:
查詢主表是:用戶表
關聯表:orders, orsertail,itesms
 
 
將用戶信息映射到user中。
在user類中添加訂單列表屬性List<Orders> orderslist,將用戶創建的訂單映射到orderslist
在Orders中添加訂單明細列表屬性List<OrderDetail>orderdetials,將訂單的明細映射到orderdetials
在OrderDetail中添加Items屬性,將訂單明細所對應的商品映射到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
來實現代碼:
在接口類中:
  //多對多findByMany
     public List<User> findByMany() throws Exception;

 xml文件中:

 
<!-- 查詢用戶及購買商品 -->  
<resultMap type="com.MrChengs.po.User" id="UserOrdaerEtc">
     <!-- User -->
     <id column="user_id" property="id"/>
     <result column="username" property="username"/>
     <result column="sex" property="sex"/>
     <result column="address" property="address"/>
     
     <!-- 訂單信息
     一個用戶對應多個訂單,使用collection映射
      -->
      <collection property="ordersList" ofType="com.MrChengs.po.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"/>
           
           <!-- 訂單明細 -->
           <collection property="orderdetails" ofType="com.MrChengs.po.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"/>
                
                <!-- 商品信息
                      一個訂單明細對應一個商品
                 -->
                  <association property="items" javaType="com.MrChengs.po.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>    
     <select id="findByMany" resultMap="UserOrdaerEtc">
                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>

 測試類:

//多對多的查詢
           @Test
           public void testfindByMany() throws Exception {
                SqlSession sqlSession = getSqlSessionFactory().openSession();
                
                //代理對象
                OrderMapperCustomer mapper = sqlSession.getMapper(OrderMapperCustomer.class);
                
                //測試findOrderUsers
                List<User> orders = mapper.findByMany();
                
                for(User order : orders){
                     System.out.println(order);
                }
                
                sqlSession.close();
           }

 

 
 
 
多對多查詢的總結:
將查詢用戶購買的商品信息明細清單,(用戶名、用戶地址、購買商品名稱、購買商品時間、購買商品數量)
針對上邊的需求就使用resultType將查詢到的記錄映射到一個擴展的pojo中,很簡單實現明細清單的功能。
一對多是多對多的特例,如下需求:
查詢用戶購買的商品信息,用戶和商品的關系是多對多關系。
需求1:
查詢字段:用戶賬號、用戶名稱、用戶性別、商品名稱、商品價格(最常見)
企業開發中常見明細列表,用戶購買商品明細列表,
使用resultType將上邊查詢列映射到pojo輸出。
需求2:
查詢字段:用戶賬號、用戶名稱、購買商品數量、商品明細()
使用resultMap將用戶購買的商品明細列表映射到user對象中。
總結:
使用resultMap是針對那些對查詢結果映射有特殊要求的功能,,比如特殊要求映射成list中包括 多個list。
 
 
 
 
result Type & resultMap:
resultType:
作用:
將查詢結果按照sql列名pojo屬性名一致性映射到pojo中。
 
場合:
常見一些明細記錄的展示,比如用戶購買商品明細,將關聯查詢信息全部展示在頁面時,此時可直接使用resultType將每一條記錄映射到pojo中,在前端頁面遍歷list(list中是pojo)即可。
 
resultMap:
使用association和collection完成一對一和一對多高級映射(對結果有特殊的映射要求)。
 
associatio:
作用:
將關聯查詢信息映射到一個pojo對象中。
場合:
為了方便查詢關聯信息可以使用association將關聯訂單信息映射為用戶對象的pojo屬性中,比如:查詢訂單及關聯用戶信息。
使用resultType無法將查詢結果映射到pojo對象的pojo屬性中,根據對結果集查詢遍歷的需要選擇使用resultType還是resultMap。
 
collection:
作用:
將關聯查詢信息映射到一個list集合中。
場合:
為了方便查詢遍歷關聯信息可以使用collection將關聯信息映射到list集合中,比如:查詢用戶權限范圍模塊及模塊下的菜單,可使用collection將模塊映射到模塊list中,將菜單列表映射到模塊對象的菜單list屬性中,這樣的作的目的也是方便對查詢結果集進行遍歷查詢。
如果使用resultType無法將查詢結果映射到list集合中。
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM