1. 程式人生 > >Mybatis多表查詢(一對一、一對多、多對多)

Mybatis多表查詢(一對一、一對多、多對多)

關聯 表屬性 msn rand tro 對象屬性 reat posit rim

Mybatis的多表級聯查詢 。

一對一可以通過實現,一對多和多對多通過實現。

元素,可以靈活選擇屬性column使用哪個字段進行鑒別。

一. 一對一的級聯查詢

對user_t表和book_t表進行連接查詢。sql語句類似如下:

select b.book_id,b.name,b.publishers,a.id,a.user_name
from user_t a
inner join book_t b on b.book_id=a.id
當然,sql語句也可以是成普通的多表級聯查詢,如下所示:

select   b.book_id,b.name,b.publishers,a.id,a.user_name
from user_t  a ,book_t  b 
where b.book_id=a.id

在User類中添加Book類的對象,還要加上getter()和setter(),以便在UserMapper.xml中進行映射。如下示:

public class User {
    private Integer id;
    private String userName;
    private String password;
    private Integer age;

//添加Book對象,還有getter(),setter()方法    
    private Book book;

    public Book getBook() {
        return book;
    }
    public void setBook(Book book) {
        this.book = book;
    }

//以下還有其他的getter(),setter(),本文忽略不寫
//  ......
}    

UserMapper.xml如下示:

中,數據表user_t的字段映射User對象的屬性。

表示主鍵,裏面是其他字段。

而其中的 中的property,對應在User類中新添加的Book類對象屬性

  <!--新建resultMap,其中的<id>為主鍵,-->
  <resultMap id="userIdMap" type="com.model.User" >
    <id column="id" property="id"/>
    <result column="user_name" property="userName" />
 <!-- association 中的property對應User類中新添加的Book類對象屬性    -->
    <association property="book" javaType="com.model.Book">
         <result column="book_id" property="bookId"  />
         <result column="name" property="name" />
         <result column="publishers" property="publishers" />
    </association>
    <!-- 方式2 -->
    <association property='book' column="book_id" select="selectBook"/>
  </resultMap>


  <!-- 根據id連接user表和book表,結果映射為上面新建的resultMap  -->
  <select id="selectBookInfoByUserId" resultMap="userIdMap">
    select   b.book_id,b.name,b.publishers,a.id,a.user_name
    from user_t  a
    inner join book_t  b on b.book_id=a.id
  </select>

二、一對多的級聯查詢

一個User擁有多個Role。查看某個用戶擁有哪些角色的sql語句,類似如下:

   SELECT  a.userName,a.name,b.uid,b.role_id   FROM  user_info a
     INNER JOIN sys_user_role b
     ON  a.uid=b.uid
     WHERE  a.userName="admin"

同樣的,在User類中添加角色列表屬性List roleIdList,還要加上getter()和setter(),以便在UserMapper.xml中進行映射如下所示:

 public class User {
    private String uid;
    //帳號
    private String userName;
    //名稱
    private String name;
    //密碼
    private String password;


//添加roleIdList屬性和對應的getter(),setter()    
    private List<SysUserRole> roleIdList;
 
    public List<SysUserRole> getRoleIdList() {
        return roleIdList;
    }

    public void setRoleIdList(List<SysUserRole> roleIdList) {
        this.roleIdList = roleIdList;
    }

    
}    

在UserMap添加如下:


  <!--   一對多級聯查詢  -->
  <resultMap id="userRoleIdMap" type="com.example.demo.pojo.User" >
    <id column="uid" property="uid" />
    <result   column="userName" property="userName" />
  
    <result column="password" property="password" />

    <collection property="roleIdList" ofType="com.example.demo.pojo.SysUserRole" >
         <id  column="role_id" property="roleId"/>
         <result   column="uid" property="uid" />
    </collection>
  </resultMap>
  <select id="findRoleIdByUserName"  resultMap="userRoleIdMap"  parameterType="java.lang.String">
     SELECT  a.userName,a.name,b.uid,b.role_id   FROM  user_info a
     INNER JOIN sys_user_role b
     ON  a.uid=b.uid
     WHERE  a.userName=#{userName}
  </select>

註意:

在一對一的查詢中, 是通過 javaType 的定義去聲明實體映射的。
一對一有兩種方式,一種是在中寫select,另一種是JavaType

而 在一對多的查詢中,則是使用 oftype 進行聲明的。

三、更復雜的多個表的一對多的級聯查詢

1.需求

查詢用戶及用戶購買的商品信息。

2.sql語句

查詢主表:用戶表

關聯表:由於用戶和商品沒有直接關聯,通過訂單和訂單明細進行關聯,所有關聯表: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

3.映射思路

將用戶信息映射到user中。

在User類中添加訂單列表屬性List orderslist,將用戶創建的訂單映射到orderslist;

在Orders中田間訂單明細列表屬性List orderdetails,將訂單的明細映射到orderdetails;

在OrderDetail中添加Items屬性,將訂單明細所對應的商品映射到Items。

  1. 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>

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>

6.mapper.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;
}

四、多對多的級聯查詢

現實中有許多用戶 , 一個用戶可以對應多個角色,而一個角色又可以由多個用戶擔當,

這個時候用戶和角色是以一張用戶角色表建立關聯關系,這樣用戶和角色就是多對多的關系

在程序中,多對多的級聯查詢往往會被拆分為兩個一對多來處理。

首先,按照示例二的一對多的級聯查詢,

一個用戶對應多個角色, 需要在用戶類User中添加角色列表屬性 List roleIdList;以及該屬性的getter()和setter()。

同理的,一個角色對應多個用戶,需要在角色類Role中添加用戶列表屬性 List userIdList; 以及該該屬性的getter()和setter()。

其余步驟和示例二一樣。

五、 元素

元素,鑒別器 , 它的屬性 column 代表使用哪個字段進行鑒別。

示例如下:

<resultMap type="com.ssm.chapterS.poJo.Employee" id="employee">
<id column="id" property="id"/>
<result column="real name" property="realName"/>
<result column="sex" property="sex" typeHandler="com.ssm.chapter5.
typeHandler.SexTypeHandler"/>
<result column="birthday" property="birthday"/>
<result column="mobile"  property="mobile"/>
<result column="email"  property="email"/>
<result column="position"  property="position"/>
<result column="note"  property="note"/>
 
<discriminator javaType="long" column="sex">
<case value="1" resultMap="maleHealthFormMapper"/>
<case value="2" resultMap="femaleHealthFormMapper"/>
</discriminator>
</resultMap>

這裏的column是 sex ,而它的子元素 case,則用於進行分類選擇 , 類似於 Java 的 switch...case...語句。
而 resultMap 屬性表示采用哪個 ResultMap 去映射 。

當 sex=l時 ,則 使用maleHealthFormMapper 進行映射。

當sex=2時,則使用femaleHealthFormMapper進行映射。

Mybatis多表查詢(一對一、一對多、多對多)