19_高级映射:一对多查询(使用resultMap)
Posted HigginCui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)的主要内容,如果未能解决你的问题,请参考以下文章