Mybatis多表查询(一对一、一对多、多对多)(转)

摘要:
Mybatis的多表级联查询。一对一可以实现,一对多、多对多可以实现。sql语句类似于以下内容:selectb.book _ id,b.name,b.publishers,a.id,a.user _ namefromuser_ tainnerjoinbook_ tbonb.book _ id=a.id当然,sql语句也可以是一个常见的多表级联查询,如下所示:selectb.book _ id、b.name,b.publishers、a.id,a.user _ namefromuser_ ta,book_ tbwhereb.book _ id=a.id将book类的对象添加到user类中,并将getter()和setter()添加到UserMapper中的映射。xml格式。一对一有两种方法,一种是写入选择,另一种是JavaType**。在一对多查询中,它是使用类型**3、多个表的更复杂的一对多级联查询1声明的。需要查询用户和用户购买的产品信息。

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   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   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   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    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   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多表查询(一对一、一对多、多对多)(转)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关键字和保留字验证码实现(google)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mybatis的嵌套查询(嵌套查询nested select和嵌套结果nested results查询)区别

(转自:http://blog.csdn.net/canot/article/details/51485955) Mybatis表现关联关系比hibernate简单,没有分那么细致one-to-many、many-to-one、one-to-one。而是只有两种association(一)、collection(多),表现很简洁。下面通过一个实例,来展示...

mybatis传入多个参数

需要查阅本文的基本都是需要传入多个参数的,这里记住一句话:无论你传的参数是什么样的,最后mybtis都会将你传入的转换为map的,那么既然这样,当我们要传入多个参数时,何不直接给与map类型即可,然后mapper.xml通过#{map.key}来获取值即可,这个特别适合动态搜索,或者多个参数的查询,并且可以在mapper的xml语句中通过if判断来实现若为...

mybatis查询oracle ’无效的列索引‘和ORA-00911’无效的字符‘错误

1、Caused by: java.sql.SQLException: 无效的列索引 参考文献:http://bbs.csdn.net/topics/300179772 配置的sql语句写错了 select distinct '#{pkgName}' as pkgName, '#{appName}' as app...

mybatis 报错:Caused by: java.lang.NumberFormatException: For input string

mybatis的if标签之前总是使用是否为空,今天要用到字符串比较的时候遇到了困难,倒腾半天,才在一个论坛上找到解决方法。笔记一下,如下: 转自:https://code.google.com/p/mybatis/issues/detail?id=262 错误描述: <select id="sltTreatment" resultType="com....

mybatis 详解(九)------ 一级缓存、二级缓存

上一章节,我们讲解了通过mybatis的懒加载来提高查询效率,那么除了懒加载,还有什么方法能提高查询效率呢?这就是我们本章讲的缓存。   本篇源码下载链接:http://pan.baidu.com/s/1eRHTsIm 密码:a5wn   mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解:      ①、一级缓存是SqlSession级别...

mybatis的关联查询以及count

1.多表查询,1对1的时候,最简单的做法 <resultMap id="postInfo" type="postInfoEntity"> <id property="postId" column="post_id"/> <result property="userName" column="us...