Mybatis多表查询(一对一、一对多、多对多)(转)
Mybatis的多表级联查询 。
一对一可以通过
一. 一对一的级联查询
对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,其中的<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
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>
注意:
在一对一的查询中,
一对一有两种方式,一种是在
**而 在一对多的查询中,
三、更复杂的多个表的一对多的级联查询
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中田间订单明细列表属性List
在OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items。
- 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
同理的,一个角色对应多个用户,需要在角色类Role中添加用户列表属性 List
其余步骤和示例二一样。
五、
示例如下:
<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进行映射。