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

Mybatis多表查询(一对一、一对多、多对多)的更多相关文章

  1. Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作

    Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作,单表查询,多表查询 一丶表与表之间的关系 背景: ​ ​ ​  ​ ​ 由于如果只使用一张表存储所有的数据,就会操作数 ...

  2. mybatis 一对一 一对多 多对多

    一对一 一对多 多对多

  3. MyBatis 多表查询

    1.多表设计 多表查询 a.多表设计 (1)一对一 在任意一方设计外键保存另一张表的主键,维系表和表的关系 (2)一对多 在多的一方设计外键保存一的一方的主键,维系表和表的关系 (3)多对多 设计一张 ...

  4. JAVA日记之mybatis-3一对一,一对多,多对多xml与注解配置

    1.Mybatis多表查询1.1 一对一查询1.1.1 一对一查询的模型用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单,与此同时查询出该订单所属的 ...

  5. JPA级联(一对一 一对多 多对多)注解【实际项目中摘取的】并非自己实际应用

    下面把项目中的用户类中有个:一对一  一对多  多对多的注解对应关系列取出来用于学习      说明:项目运行正常 问题类:一对多.一对一.多对多 ============一对多 一方的设置 @One ...

  6. Mybatis多表查询出现null字段

    写在前面 今天使用mybatis实现多表查询,记录一下其中遇到的坑 mybatis多表查询简介 mybatis多表查询主要有两个方式,通俗易懂的来说就是一个是查询少量属性(association),一 ...

  7. 7.Mybatis关联表查询(这里主要讲的是一对一和一对多的关联查询)

    在Mybatis中的管理表查询这里主要介绍的是一对一和一对多的关联查询的resultMap的管理配置查询,当然你也可以用包装类来实现.不过这里不说,做关联查询的步骤可以简单的总结为以下的几步: 1.分 ...

  8. day 69-70 一对一 一对多 多对一联表查询

    day 69 orm操作之表关系,多对多,多对一 多对一/一对多, 多对多{类中的定义方法} day69 1. 昨日内容回顾 1. 单表增删改查 2. 单表查询API 返回QuerySet对象的: 1 ...

  9. Mybatis多表查询之一对一查询的多种实现-XML配置

    Mybatis 中对于多表查询提供了非常强大的实现方式,主要是通过resultMap的结果映射对于多表查询后的返回值进行封装,让我们来看一下官网上对于resultMap的解释:resultMap 元素 ...

随机推荐

  1. JAVA实现Excel导入/导出【转】

    JAVA实现Excel导入/导出[转] POI的下载与安装 请到网站http://www.apache.org/dyn/closer.cgi/poi/右击超链接2.5.1.zip下载压缩包poi-bi ...

  2. springboot---没有配置数据库启动报错

    If you want an embedded database please put a supported one on the classpath. If you have database s ...

  3. 自动化测试--响应请求测试(.net)

    Web运行原理简单地说是“浏览器发送一个HTTP Request到Web服务器上,Web服务器处理完后将结果(HTTP Response)返回给浏览器”. 通常测试一个web api是否正确,可以通过 ...

  4. Java 反射机制介绍

    参考文章:http://www.cnblogs.com/skywang12345/p/3345205.html Java 反射机制.通俗来讲呢,就是在运行状态中,我们可以根据“类的部分已经的信息”来还 ...

  5. LTIB for ubuntu12.04

     在 ltib 目录中执行以下代码: cd <your ltib folder>./patch-ltib-ubuntu12.04.shpatch -p1 < patch-dist-u ...

  6. idea 使用spring boot 搭建freemarker模板

      一丶新建maven spring boot 项目 新建好了开始使用模板 先看一个目录结构 二丶配置pox.xml <?xml version="1.0" encoding ...

  7. 949. Largest Time for Given Digits

    Given an array of 4 digits, return the largest 24 hour time that can be made. The smallest 24 hour t ...

  8. Javascript 全局函数是 window 的函数

    比如以下函数,看起来不属于任何对象,但它是一个全局对象. 它属于 HTML页面的函数. function myFunction(a, b){ return a * b; } window.myFunc ...

  9. RelativeLayout相对布局 各个属性详解

    RelativeLayout相对布局 相对布局 RelativeLayout 允许子元素指定它们相对于其父元素或兄弟元素的位置,这是实际布局中最常用的布局方式之一.它灵活性大很多,当然属性也多,操作难 ...

  10. C++ 函数特性_函数重载

    函数重载 在相同作用域内 用同一函数名定义的多个函数: 参数个数和参数类型不同 int getMax(int x,int y,int z) // 函数名相同都是 getMax() { // to do ...