19_高级映射:一对多查询(使用resultMap)

【需求】

查询订单以及订单明细的信息。

确定主查询表:订单表orders

确定关联查询表:订单明细表 orderdetail

在一对一查询的基础上添加订单明细表关联即可。

【分析】

使用resultMap将上面的查询结果映射到pojo中,订单信息有重复。

要求:对orders映射不能出现重复记录

在orders.java类中添加List<orderDetail> orderDetails属性。

最终会将订单信息映射到orders中,订单所对应的订单明细映射到orders中的orderDetails属性中。如下所示:

映射成的orders记录为两条(orders信息不能重复)

每个orders中的orderDetails属性存储了该订单所对应的订单明细。

【工程截图】

【User.java】

package cn.higgin.mybatis.po;

import java.util.Date;

public class User {
    //属性名和数据库表的字段对应
    private int id;
    private String username;
    private String sex;
    private Date birthday;
    private String address;
    //set/get方法忽略.....
}

【Orderdetail.java】

package cn.higgin.mybatis.po;

public class Orderdetail {
    private Integer id;

    private Integer ordersId;

    private Integer itemsId;

    private Integer itemsNum;
    //get/set方法忽略......
}

【Orders.java】

package cn.higgin.mybatis.po;
import java.util.Date;
import java.util.List;

public class Orders {

    private Integer id;
    private Integer userId;
    private String number;
    private Date createtime;
    private String note;
    //引入用户信息
    private User user;
    //引入订单明细(和上面的用户信息不同,一个是一对一,一个是一对多)
    private List<Orderdetail> orderdetails; //注意是orderdetails,一个有‘s‘,一个有‘s‘
    //忽略set/get方法......
}
    

【OrdersMapperCustom.java】

package cn.higgin.mybatis.mapper;

import java.util.List;

import cn.higgin.mybatis.po.Orders;

public interface OrdersMapperCustom {

    //查询订单(关联用户)及订单明细
    public List<Orders> findOrdersAndOrderDetailResultMap() throws Exception;
}

【OrdersMapperCustomer.xml】

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.higgin.mybatis.mapper.OrdersMapperCustom">

    <!--
         订单查询关联用户的resultMap
        将整个查询的结果映射到cn.higgin.mybatis.po.Orders中
     -->
     <resultMap type="cn.higgin.mybatis.po.Orders" id="OrdersUserResultMap">
         <!-- 配置订单的映射信息 -->
         <!--
             id:指定查询列中的唯一标识,订单信息中的唯一标识,若有多个列组成唯一标识,需配置多个id
             column: 订单信息的唯一标识列
             property: 订单信息的唯一标识列所映射到的 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" />

          <!-- 配置映射的关联的用户信息 -->
          <!-- association:用于映射关联查询单个对象的信息
              property:要将关联查询的用户信息映射到Orders中的对应属性
           -->
           <association property="user" javaType="cn.higgin.mybatis.po.User">
               <!--
                   id:关联查询用户的唯一标识
                   column:指定唯一标识用户信息的列
                   javaType:映射到user的对应属性
                -->
                <id column="user_id" property="id"/>
                <result column="username" property="username"/>
                <result column="sex" property="sex"/>
                <result column="address" property="address"/>
           </association>
     </resultMap>

    <!-- 订单及订单明细的resultType
        使用extends继承OrdersUserResultMap中的信息,无需在其中配置订单和用户的信息
    -->
    <resultMap type="cn.higgin.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap"
        extends="OrdersUserResultMap">
        <!-- 1.订单信息(从继承的OrdersUserResultMap中获取) -->

        <!-- 2.用户信息(从继承的OrdersUserResultMap中获取) -->

        <!-- 订单明细信息
            一个订单关联查询出了多条明细,要使用collection进行映射
            collection:对关联查询到多条记录映射到集合对象中
            property: 将关联查询到多条记录映射到cn.higgin.mybatis.po.Orders的对应属性
            ofType: 指定映射到list集合属性中pojo的类型,在[Orders.java]中的 private List<Orderdetail> orderdetails;
         -->
         <collection property="orderdetails" ofType="cn.higgin.mybatis.po.Orderdetail">
             <!-- id:订单明细唯一标识
                 property:要将订单明细的唯一标识映射到cn.higgin.mybatis.po.Orderdetail的对应属性 -->
             <id column="orderdetail_id" property="id"/>
             <result column="items_id" property="id"/>
             <result column="items_num" property="itemsNum"/>
             <result column="orders_id" property="ordersId"/>
         </collection>
    </resultMap>

    <!-- 查询订单关联查询用户信息,使用resultMap -->
    <select id="findOrdersAndOrderDetailResultMap" resultMap="OrdersAndOrderDetailResultMap">
        SELECT
            orders.*,
            USER.username,
            USER.sex,
            USER.address,
            orderdetail.items_id,
            orderdetail.items_num,
            orderdetail.orders_id
        FROM
            orders,USER,orderdetail
        WHERE
            orders.user_id=user.id AND orderdetail.orders_id=orders.id
    </select> 

</mapper>

【SplMapConfig.xml 和 db.properties 与前一篇博文相同】

【OrdersMapperCustomTest.java】

package cn.higgin.mybatis.mapper;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import cn.higgin.mybatis.po.Orders;

public class OrdersMapperCustomTest {
    private SqlSessionFactory sqlSessionFactory;

    // 此方法是在执行testFindUserById之前执行
    @Before
    public void setUp() throws Exception {
        // 创建sqlSessionFactory

        // mybatis配置文件
        String resource = "SqlMapConfig.xml";
        // 得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 创建会话工厂,传入mybatis的配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testFindOrdersUser() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //创建代理对象
        OrdersMapperCustom ordersMapperCustom=sqlSession.getMapper(OrdersMapperCustom.class);

        //调用mapper的方法
        List<Orders> list=ordersMapperCustom.findOrdersAndOrderDetailResultMap();

        System.out.println(list.size());

        sqlSession.close();
    }
}

【debug运行结果】

可见只有两条记录:

再查看一下具体内容:

注意:重复的数据被合并,不重复的数据在集合中,下图作对比:

【小结】

mybatis使用resultMap的collection对关联查询的多条记录映射映射到一个list集合属性中(private List<Orderdetail> orderdetails;)。

使用resultType也可以实现:

将订单明细映射到orders中的orderdetails中,需要自己处理,使用双重循环遍历,去掉重复记录,将订单明细放在orderdetails中。

时间: 2024-10-09 09:07:01

19_高级映射:一对多查询(使用resultMap)的相关文章

MyBatis总结之高级映射一对多查询

上一篇博文总结了一下一对一的映射,本文主要总结一下一对多的映射,订单项和订单明细是一对多的关系,所以本文主要来查询订单表,然后关联订单明细表,这样就有一对多的问题出来了. 首先还是先写sql语句,在写sql语句的时候遵循两点: 查询的主表是哪个? 订单表 查询的关联表是哪个? 订单明细表 明确了主表和关联表,下面就可以写sql了,我们在上一节的sql基础上添加订单明细表的关联即可. SELECT orders.*, user.`username`, user.`sex`, user.`addre

【MyBatis学习08】高级映射之一对一查询

从这一篇博文开始,将总结一下mybatis中的几个高级映射,即一对一.一对多.多对多查询,这篇先总结一下mybatis中的一对一查询. 为了模拟这些需求,事先要建立几个表,不同的表之间将对应上面提到的不同的映射,为此,我建立4个表,如下: DROP TABLE IF EXISTS `items`; DROP TABLE IF EXISTS `orders`; DROP TABLE IF EXISTS `user`; DROP TABLE IF EXISTS `orderdetail`; /*it

17_高级映射:一对一查询(使用resultType)

[数据库模型] [各个表] [ 用户表user ] 购买商品的用户信息. [ 订单表 ] 用户所创建的订单 [ 订单明细表 ] 订单的详细信息,即购买商品的信息 [ 商品表 ] 商品的具体信息 [有关系的表之间的业务关系] 分析表与表之间的业务关系时,需要建立在某个业务意义的基础之上去分析. [ user 与 orders ] user ---> orders :一个用户可以创建多个订单, 一对多 orders ---> user :一个订单只能由一个用户创建,一对一 [ orders与ord

Mybatis深入了解(六)----关联查询(高级映射)

一对一查询 resultType resultMap 一对多查询 resultType resultMap 多对多查询 一对一查询 resultType resultType:使用resultType实现非常简单,如果POJO中没有包括查询的列名,可以新建扩展类继承父类,并在子类中添加列名对应的属性,即可完成映射. package cn.itcast.ssm.po; /** * 订单的扩展类 * @author Administrator * */ //通过此类映射订单和用户查询的结果,让此类继

Mybatis学习笔记(三)—高级映射,延迟加载

本文主要介绍了如何使用resultMap完成高级映射:分析数据库中表之间的关系(一对一.一对多.多对多) 如何在mapper.xml文件中配置resultMap实现一对一.一对多.多对多:mybatis如何实现延迟加载 1       数据模型 数据库中有已经导入的四个表:items:(商品信息表):orderdetail:(订单明细表):orders:(订单表):user:(用户表) 1 CREATE TABLE items ( 2 id INT NOT NULL AUTO_INCREMENT

mybatis0205 一对多查询 复杂

查询所有用户信息,关联查询订单及订单明细信息及商品信息,订单明细信息中关联查询商品信息 1.1sql 主查询表:用户信息 关联查询:订单.订单明细,商品信息 SELECT orders.*, user.username, user.sex , orderdetail.id orderdetail_id, orderdetail.items_num, orderdetail.items_id, items.name items_name, items.detail items_detail FRO

mybatis0204 一对多查询

查询所有订单信息及订单下的订单明细信息. sql语句 主查询表:订单表 关联查询表:订单明细 SELECT orders.*, user.username, user.sex , orderdetail.id orderdetail_id, orderdetail.items_num, orderdetail.items_id FROM orders, USER, orderdetail WHERE orders.user_id = user.id AND orders.id = orderde

mybatis入门基础(六)----高级映射(一对一,一对多,多对多)

一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: 1 CREATE TABLE items ( 2 id INT NOT NULL AUTO_INCREMENT, 3 itemsname VARCHAR(32) NOT NULL COMMENT '商品名称', 4 price FLOAT(10,1) NOT NULL COMMENT '商品定价', 5 detail TEXT COMMENT '商品描述', 6 pic VARCHAR(64) DEFAULT NULL COMMENT

Mybatis(四) 高级映射,一对一,一对多,多对多映射

天气甚好,怎能不学习? 一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部门,一个部门中有多个员工,从部门方看,是一对多关系,而多名员工属于一个部门,是多对一关系,那么如果我们的业务需求只需要通过部门查找到所有的员工,那么我们就只需要进行单向一对多的映射,如果我们需要通过员工来查询出对应的部门,那么我们就需要进行单向多对一的映射,而如果我们这两个业