首页 > 代码库 > 19_高级映射:一对多查询(使用resultMap)

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中。

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