21Mybatis_订单商品数据模型_一对多查询——resultMap方式

这篇文章延续订单商品数据模型,这张讲述的是一对多的查询。(用resultMap)

给出几张表的内容:

User表:

orders表:

orderdetail表:

orders表:

items表:

在SQLyog中写一个sql语句 (先验证成功):

SELECT
  orders.*,
  USER.username,
  USER.sex,
  USER.address,
  orderdetail.id orderdetail_id,
  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

结果是:

其实我们要做的就是:把上面查出来的那个数据表每个字段映射好!!!

好,现在开始:

先给出需求:

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

我们由前面的文章知道查询订单及订单明细的信息是一对多的关系。

我们还是按照:1.sql 2.pojo映射类3.mapper.xml和mapper.java接口这种顺序。

1.sql语句:

确定主查询表:订单表

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

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

SELECT

orders.*,

USER.username,

USER.sex,

USER.address,

orderdetail.id orderdetail_id,//别名orderdetail_id

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

这种sql查询出来的结果是:

很明显查询出来的结果是重复的(两个id为3的数据,两个id为4的数据,为什么会出现这样的结果,原因是:

我们知道一张订单表会对应多个订单明细表,这样的话就是说一个用户有一张订单表,那么一张订单表上肯定有很多的订单信息表

但是上面的这样结果如果用resultType来做的:使用resultType将上边的 查询结果映射到pojo中,订单信息的就是重复。我们采用的是resultMap.

但是我们的需求是:对orders映射不能出现重复记录。

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

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

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

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

效果如下:

上面图Orders只有两条信息,每个Orders中的各有两条orderDetails信息。这样就刚好一一对应了。一对多——完美!

2.根据上面的思路来创建pojo类:

package cn.itcast.mybatis.po;

import java.util.Date;
import java.util.List;

public class Orders {
private Integer id;
private Integer user_id;
private String number;
private Date createtime;
private String note;
//用户信息,新增了一个User属性,为了保存查询得到的关联的User表的信息(一对一)
private User user;
//订单明细。order关联多个orderdetails,(一对多)
private List<Orderdetail> orderdetails;

public List<Orderdetail> getOrderdetail() {
    return orderdetails;
}
public void setOrderdetail(List<Orderdetail> orderdetail) {
    this.orderdetails = orderdetail;
}
public User getUser() {
    return user;
}
public void setUser(User user) {
    this.user = user;
}
public Integer getId() {
    return id;
}
public void setId(Integer id) {
    this.id = id;
}
public Integer getUser_id() {
    return user_id;
}
public void setUser_id(Integer user_id) {
    this.user_id = user_id;
}
public String getNumber() {
    return number;
}
public void setNumber(String number) {
    this.number = number;
}
public Date getCreatetime() {
    return createtime;
}
public void setCreatetime(Date createtime) {
    this.createtime = createtime;
}
public String getNote() {
    return note;
}
public void setNote(String note) {
    this.note = note;
}

}

3.创建mapper.xml和mapper.java接口。

OrdersMapperCustom.xml代码如下:

OrdersMapperCustom.xm写法一:

<?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">
<!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离

注意:使用mapper代理方式,namespace有特殊重要的作用
-->

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

        <!-- 配置映射的订单信息 -->
        <!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
          就是说id要能唯一的标识出数据库中的Order表。
            column:订单信息的唯 一标识 列
            property:订单信息的唯 一标识 列所映射到Orders中哪个属性

          -->

<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap">
   <!-- 这一行的作用是要能唯一的识别出order表的,那么很明显是主键id -->
    <id column="id" property="id"/>

    <!-- 以下的几行result column就是表中的字段   property就是对应到相应pojo类中的属性-->
    <result column="user_id" property="user_id"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note"  property="note"/>
    <!-- 配置映射的关联的用户信息 -->
        <!-- association:用于映射关联查询单个对象的信息
        property:要将关联查询的用户信息映射到Orders中哪个属性
         -->
    <!-- 下面的代码比较特殊,因为Order表是直接关联到user表,下面这么写的目的是把user表映射到Order类中
     <association property="user"这里的user指的是orders类中的user,对应的是cn.itcast.mybatis.po.User
     -->
    <association property="user" javaType="cn.itcast.mybatis.po.User">
       <!--
       <id column="user_id" property="id"/>这里的是user_id指的是order表中只有这个属性能表示唯一的user表
        -->
        <id column="user_id" property="id"/>

        <!-- 接下来的result  property什么的都是为了把user表中的字段能匹配到
        cn.itcast.mybatis.po.User这个类的属性中
        -->
           <result column="username" property="username"/>
          <result column="sex" property="sex"/>
          <result column="address" property="address"/>
        </association>

</resultMap>

    <resultMap type="cn.itcast.mybatis.po.Orders"  id="OrderAndOrderDetailResultMap">
     <!-- 订单和用户的设置 -->
        <id column="id" property="id"/>
    <!-- 以下的几行result column就是表中的字段   property就是对应到相应pojo类中的属性-->
    <result column="user_id" property="user_id"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note"  property="note"/>
    <!-- 配置映射的关联的用户信息 -->
        <!-- association:用于映射关联查询单个对象的信息
        property:要将关联查询的用户信息映射到Orders中哪个属性
         -->
    <!-- 下面的代码比较特殊,因为Order表是直接关联到user表,下面这么写的目的是把user表映射到Order类中
     <association property="user"这里的user指的是orders类中的user属性,对应的是cn.itcast.mybatis.po.User
     -->
    <association property="user" javaType="cn.itcast.mybatis.po.User">
       <!--
       <id column="user_id" property="id"/>这里的是user_id指的是order表中只有这个属性能表示唯一的user表
        -->
        <id column="user_id" property="id"/>

        <!-- 接下来的result  property什么的都是为了把user表中的字段能匹配到
        cn.itcast.mybatis.po.User这个类的属性中
        -->
           <result column="username" property="username"/>
          <result column="sex" property="sex"/>
          <result column="address" property="address"/>
        </association>

    <!-- 订单明细信息
               一个订单关联查询出了多条明细,要使用collection进行映射
        collection:对关联查询到多条记录映射到集合对象中
        property:将关联查询到多条记录映射到cn.itcast.mybatis.po.Orders哪个属性
        ofType:指定映射到list集合属性中pojo的类型

    -->
    <!--
    其是要理解collection的话对比上面的association,association是一对一的映射,而collection是一对多的映射
    <collection property="orderdetails" 这里的orderdetails是Orders中一个属性:private List<Orderdetail> orderdetails;
    ofType="cn.itcast.mybatis.po.Orderdetail"这里的
    cn.itcast.mybatis.po.Orderdetail是List<Orderdetail>里面的Orderdetail类型。

     -->

    <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">

             <!-- id:订单明细唯 一标识
             property:要将订单明细的唯 一标识 映射到cn.itcast.mybatis.po.Orderdetail的哪个属性
               -->
          <!-- 这里的<id column="orderdetail_id" property="id"/>
        orderdetail_id是要唯一能标识orderdetail表的字段,所以选了orderdetail的主键,为什么是orderdetail_id
          而不是id呢,原因是为了避免和orders表的id造成冲突,所以取的别名。property="id"是cn.itcast.mybatis.po.Orderdetail
          中的属性
         -->
        <id column="orderdetail_id" property="id"/>
        <!-- 这里的result 中column都是orderdetail表中的字段,property是Orderdetail中的属性,要一一映射过去 -->
        <result column="items_id" property="items_id"/>
        <result column="items_number" property="items_num"/>
         <result column="orders_id" property="orders_id"/>
    </collection>

    </resultMap>

        <select id="findOrdersUser"  resultType="cn.itcast.mybatis.po.OrdersCustom">
        SELECT ORDERS.* ,
        user.`username`,
        user.`sex`,
        user.`address`
        FROM orderS,USER
         WHERE ORDERS.`user_id`=USER.`id`

    </select>

      <select id="findOrdersUseResultMap"  resultMap="OrdersUserResultMap">
        SELECT ORDERS.* ,
        user.`username`,
        user.`sex`,
        user.`address`
        FROM orderS,USER
         WHERE ORDERS.`user_id`=USER.`id`

    </select>

      <select id="findOrdersandOrderDetailResultMap" resultMap="OrderAndOrderDetailResultMap">
        SELECT ORDERS.* ,
        user.`username`,
        user.`sex`,user.`address`,
        orderdetail.`id` orderdetail_id ,
        orderdetail.`items_id`,
        orderdetail.`items_num`
        FROM orderS,USER ,orderdetail
        WHERE ORDERS.`user_id`=USER.`id`AND orderdetail.`orders_id`=Orders.`id`  

      </select>

</mapper>

OrdersMapperCustom.xm写法二:

发现上面的写法有点复杂,有些代码重复了,我们可以用extends这种做法来避免写重复代码。

<?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">
<!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离

注意:使用mapper代理方式,namespace有特殊重要的作用
-->

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

        <!-- 配置映射的订单信息 -->
        <!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
          就是说id要能唯一的标识出数据库中的Order表。
            column:订单信息的唯 一标识 列
            property:订单信息的唯 一标识 列所映射到Orders中哪个属性

          -->

<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap">
   <!-- 这一行的作用是要能唯一的识别出order表的,那么很明显是主键id -->
    <id column="id" property="id"/>

    <!-- 以下的几行result column就是表中的字段   property就是对应到相应pojo类中的属性-->
    <result column="user_id" property="user_id"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note"  property="note"/>
    <!-- 配置映射的关联的用户信息 -->
        <!-- association:用于映射关联查询单个对象的信息
        property:要将关联查询的用户信息映射到Orders中哪个属性
         -->
    <!-- 下面的代码比较特殊,因为Order表是直接关联到user表,下面这么写的目的是把user表映射到Order类中
     <association property="user"这里的user指的是orders类中的user,对应的是cn.itcast.mybatis.po.User
     -->
    <association property="user" javaType="cn.itcast.mybatis.po.User">
       <!--
       <id column="user_id" property="id"/>这里的是user_id指的是order表中只有这个属性能表示唯一的user表
        -->
        <id column="user_id" property="id"/>

        <!-- 接下来的result  property什么的都是为了把user表中的字段能匹配到
        cn.itcast.mybatis.po.User这个类的属性中
        -->
           <result column="username" property="username"/>
          <result column="sex" property="sex"/>
          <result column="address" property="address"/>
        </association>

</resultMap>

 <!-- 

用extends OrdersUserResultMap
的话上面的重复代码就不用谢了
-->
    <resultMap type="cn.itcast.mybatis.po.Orders"  id="OrderAndOrderDetailResultMap"
        extends="OrdersUserResultMap">

    <!-- 订单明细信息
               一个订单关联查询出了多条明细,要使用collection进行映射
        collection:对关联查询到多条记录映射到集合对象中
        property:将关联查询到多条记录映射到cn.itcast.mybatis.po.Orders哪个属性
        ofType:指定映射到list集合属性中pojo的类型

    -->
    <!--
    其是要理解collection的话对比上面的association,association是一对一的映射,而collection是一对多的映射
    <collection property="orderdetails" 这里的orderdetails是Orders中一个属性:private List<Orderdetail> orderdetails;
    ofType="cn.itcast.mybatis.po.Orderdetail"这里的
    cn.itcast.mybatis.po.Orderdetail是List<Orderdetail>里面的Orderdetail类型。

     -->

    <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">

             <!-- id:订单明细唯 一标识
             property:要将订单明细的唯 一标识 映射到cn.itcast.mybatis.po.Orderdetail的哪个属性
               -->
          <!-- 这里的<id column="orderdetail_id" property="id"/>
        orderdetail_id是要唯一能标识orderdetail表的字段,所以选了orderdetail的主键,为什么是orderdetail_id
          而不是id呢,原因是为了避免和orders表的id造成冲突,所以取的别名。property="id"是cn.itcast.mybatis.po.Orderdetail
          中的属性
         -->
        <id column="orderdetail_id" property="id"/>
        <!-- 这里的result 中column都是orderdetail表中的字段,property是Orderdetail中的属性,要一一映射过去 -->
        <result column="items_id" property="items_id"/>
        <result column="items_number" property="items_num"/>
         <result column="orders_id" property="orders_id"/>
    </collection>

    </resultMap>

        <select id="findOrdersUser"  resultType="cn.itcast.mybatis.po.OrdersCustom">
        SELECT ORDERS.* ,
        user.`username`,
        user.`sex`,
        user.`address`
        FROM orderS,USER
         WHERE ORDERS.`user_id`=USER.`id`

    </select>

      <select id="findOrdersUseResultMap"  resultMap="OrdersUserResultMap">
        SELECT ORDERS.* ,
        user.`username`,
        user.`sex`,
        user.`address`
        FROM orderS,USER
         WHERE ORDERS.`user_id`=USER.`id`

    </select>

      <select id="findOrdersandOrderDetailResultMap" resultMap="OrderAndOrderDetailResultMap">
        SELECT ORDERS.* ,
        user.`username`,
        user.`sex`,user.`address`,
        orderdetail.`id` orderdetail_id ,
        orderdetail.`items_id`,
        orderdetail.`items_num`
        FROM orderS,USER ,orderdetail
        WHERE ORDERS.`user_id`=USER.`id`AND orderdetail.`orders_id`=Orders.`id`  

      </select>

</mapper>

OrdersMapperCustom.java接口如下:

package cn.itcast.mybatis.mapper;

import java.util.List;

import cn.itcast.mybatis.po.Orders;
import cn.itcast.mybatis.po.OrdersCustom;

public interface OrdersMapperCustom {
    //函数的名字OrdersMapperCustom.xml中select中的id名一样
    public List<OrdersCustom> findOrdersUser();
    public List<Orders> findOrdersUseResultMap();
    public List<Orders> findOrdersandOrderDetailResultMap();

}

Junit测试代码:

Mybatis_mappertest.java代码如下:

package cn.itcast.mybatis.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
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.itcast.mybatis.mapper.OrdersMapperCustom;
import cn.itcast.mybatis.mapper.userMapper;
import cn.itcast.mybatis.po.Orders;
import cn.itcast.mybatis.po.User;
import cn.itcast.mybatis.po.UserCustom;
import cn.itcast.mybatis.po.UserQueryVo;

public class Mybatis_mappertest {

    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void setup() throws IOException
    {   String resource="SqlMapConfig.xml";
        InputStream inputStream= Resources.getResourceAsStream(resource);
        //主要是生成SqlsessionFactory。
        this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testMaper()
    {
        SqlSession sqlSession=null;

        sqlSession=sqlSessionFactory.openSession();
        //生成代理类
        OrdersMapperCustom orderMapper=sqlSession.getMapper(OrdersMapperCustom.class);

       @SuppressWarnings("unused")
    //List<Orders>list=orderMapper.findOrdersUseResultMap();
        List<Orders> list=orderMapper.findOrdersandOrderDetailResultMap();

    }

}

一对多总结:

mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。

时间: 2024-12-27 09:39:50

21Mybatis_订单商品数据模型_一对多查询——resultMap方式的相关文章

22Mybatis_订单商品数据模型_多对多查询以及对多对多查询的总结

之前讲了一对一,一对多查询,这篇文章讲的是多对多. 先给出需求:查询用户及用户购买商品信息. 我们由之前的文章知道,这个需求是多对多的. 还是那个终止我们的mybatis所做的不管是之前的一对一还是一对多还是多对多,都只是为了把查询出来的结果(每个字段)做好映射. 好,我们现在sqlyong上把数据查出来,然后做映射. 给出几张表的内容: User表: orderdetail表: orders表: items表: 我们根据需求(查询用户及用户购买商品信息)把sql语句写出来: sql: SELE

20Mybatis_订单商品数据模型_一对一查询——resultType和resultMap两种方式以及两种方式的总结

上一篇文章分析了数据模型,这篇文章就给出一个需求,这个需求是一对一查询,并完成这个需求. -------------------------------------------------------------------------------------------------------------------------------------------- 需求: 查询订单信息,关联查询创建订单的用户信息. 记住:用Mybatis开发的顺序就是 1.写sql语句 2.创建pojo类来

订单商品数据模型-分析思路

我们接下来要对即将用来实验的订单商品数据模型进行分析. 首先在MySql中创建数据库,在其中创建以下表: CREATE TABLE `items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL COMMENT '商品名称', `price` float(10,1) NOT NULL COMMENT '商品定价', `detail` text COMMENT '商品描述', `pic` varchar(64)

mybatis学习笔记(9)-订单商品数据模型分析

mybatis学习笔记(9)-订单商品数据模型分析 mybatis学习笔记9-订单商品数据模型分析 数据模型分析思路 数据模型分析 订单商品数据模型建表sql 本文对接下来几篇博客中用到的数据模型进行分析,并附上建表sql文件和测试数据文件 数据模型分析思路 每张表记录的数据内容 分模块对每张表记录的内容进行熟悉,相当于你学习系统需求(功能)的过程. 每张表重要的字段设置 非空字段.外键字段 数据库级别表与表之间的关系 外键关系 表与表之间的业务关系 在分析表与表之间的业务关系时一定要建立在某个

mybatis入门截图四(订单商品数据模型 一对一,一对多,多对多)

--------------------------------- 一对一查询 查询订单信息,关联查询创建订单的用户信息 1.高级映射-一对一查询-使用resultType 2.高级映射-一对一查询-使用resultMap 在mapper.xml中定义映射的ResultMap <!-- 订单查询关联用户的resultMap 将整个查询的结果映射到cn.itcast.mybatis.po.Orders中 --> <resultMap type="cn.itcast.mybatis

23Mybatis_根据订单商品数据模型的练习对resultMap和resulttype的总结

resultType: 作用: 将查询结果按照sql列名pojo属性名一致性映射到pojo中. 场合: 常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可. resultMap: 使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求). association: 作用: 将关联查询信息映射到一个pojo对象中.

java-mybaits-00501-案例-映射分析-订单商品数据模型

1.数据模型分析思路 1.每张表记录的数据内容 分模块对每张表记录的内容进行熟悉,相当 于你学习系统 需求(功能)的过程. 2.每张表重要的字段设置 非空字段.外键字段 3.数据库级别表与表之间的关系 外键关系 4.表与表之间的业务关系 在分析表与表之间的业务关系时一定要建立 在某个业务意义基础上去分析. 2.数据模型分析 用户表user: 记录了购买商品的用户信息 订单表:orders 记录了用户所创建的订单(购买商品的订单) 订单明细表:orderdetail: 记录了订单的详细信息即购买商

数据模型图解分析(用户订单商品)

对订单商品数据模型进行分析 数据模型分析思路 1 每张表记录的数据内容 分模块对每张表记录的内容进行熟悉,相当于你学习系统需求(功能)的过程. 2 每张表重要字段设置 非空字段.外键字段 3 数据库级别表与表之间的关系 外键关系 4 表与表之间的业务关系 在分析表与表之间的业务关系时候,一定要建立在某个业务意义的基础上进行分析 订单模型分析图解 数据模型分析 用户表user: 记录了购买商品的用户信息 订单表orders:记录了用户所创建的订单(购买商品的订单)[外键 user_id] 订单明细

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