zoukankan      html  css  js  c++  java
  • Mybatis多表查询(一对一、一对多、多对多)(转)

    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进行映射。

  • 相关阅读:
    成绩等级
    函数值
    最大数
    温度转换
    何时使用hadoop fs、hadoop dfs与hdfs dfs命令
    Hadoop常见异常及其解决方案
    Hadoop2.4.1入门实例:MaxTemperature
    单机/伪分布式Hadoop2.4.1安装文档
    用Apache Ivy实现项目里的依赖管理
    【Nutch2.2.1基础教程之2.1】集成Nutch/Hbase/Solr构建搜索引擎之一:安装及运行【单机环境】
  • 原文地址:https://www.cnblogs.com/imjamin/p/10641189.html
Copyright © 2011-2022 走看看