Mybatis的多表級聯查詢 。
一對一可以通過<association>實現,一對多和多對多通過<collection>實現。
<discriminator> 元素,可以靈活選擇屬性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如下示:
在<resultMap>中,數據表user_t的字段映射User對象的屬性。
<id>表示主鍵,<result>里面是其他字段。
而其中的 <association> 中的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> </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<SysUserRole> 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>
注意:
在一對一的查詢中,<association> 是通過 javaType 的定義去聲明實體映射的。
而 在一對多的查詢中,<collection>則是使用 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<Orders> orderslist,將用戶創建的訂單映射到orderslist;
在Orders中田間訂單明細列表屬性List<OrderDetail> orderdetails,將訂單的明細映射到orderdetails;
在OrderDetail中添加Items屬性,將訂單明細所對應的商品映射到Items。
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>
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<SysUserRole> roleIdList;以及該屬性的getter()和setter()。
同理的,一個角色對應多個用戶,需要在角色類Role中添加用戶列表屬性 List<User> userIdList; 以及該該屬性的getter()和setter()。
其余步驟和示例二一樣。
五、<discriminator> 元素
<discriminator> 元素,鑒別器 , 它的屬性 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進行映射。
更多詳情,參考博客 :https://www.cnblogs.com/Joanna-Yan/p/6923464.html