首页 > 技术文章 > 20_高级映射:多对多查询

HigginCui 2016-09-07 20:40 原文

【需求】

查询用户及用户购买的商品信息。

【SQL语句】

查询主表:用户user表

关联表:由于用户和商品没有直接关联,需通过订单和订单明细进行关联,所以关联的表是 orders、orderdetail、items

 

【映射的思路】

将用户信息映射到user中。

在user类中添加订单列表属性List<Orders> orderlist,将用户创建的订单映射到orderslist。

在Orders中添加订单明细列表属性List<OrderDetail> orderdetails,将订单的明细映射到orderdetails。

在OrderDetails中添加items属性,将订单明细所对应的商品映射到items。

 

【工程截图】

 

【Items.java】

package cn.higgin.mybatis.po;

import java.util.Date;

public class Items {
    private Integer id;
    private String name;
    private Float price;
    private String pic;
    private Date createtime;
    private String detail;
    //忽略get/set方法.......
}

【Orderdetail.java】

package cn.higgin.mybatis.po;

public class Orderdetail {
    private Integer id;

    private Integer ordersId;

    private Integer itemsId;

    private Integer itemsNum;

    //订单明细对应的商品信息
    private Items items;
    //忽略get/set方法......
}

【】

 

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;
    //忽略get/set方法......
}

【User.java】

package cn.higgin.mybatis.po;

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

public class User {
    //属性名和数据库表的字段对应
    private int id;
    private String username;
    private String sex;
    private Date birthday;
    private String address;
    
    //用户创建的订单列表
    private List<Orders> ordersList;
    //忽略get/set方法......
}

 

【OrdersMapperCustom.java】

package cn.higgin.mybatis.mapper;

import java.util.List;

import cn.higgin.mybatis.po.User;

public interface OrdersMapperCustom {
    
    //查询用户购买商品信息
    public List<User> findUserAndItemsResultMap() throws Exception;
}

【OrdersMapperCustom.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 type="cn.higgin.mybatis.po.User" id="UserAndItemsResultMap">
        <!-- 1.用户信息 -->
        <id column="user_id" property="id"/>
        <id column="username" property="username"/>
        <id column="sex" property="sex"/>
        <id column="address" property="address"/>
        
        <!-- 2.订单信息 (一个用户对应对个订单,所以用collection映射)-->
        <collection property="ordersList" ofType="cn.higgin.mybatis.po.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"/>
            <!-- 订单明细(一个订单包括多个订单明细) -->
            <collection property="orderdetails" ofType="cn.higgin.mybatis.po.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"/>
                 <!-- 商品信息(一个订单明细对应一个商品) -->
                 <association property="items" javaType="cn.higgin.mybatis.po.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>
    
    <!-- 查询订单关联查询用户信息,使用resultMap -->
    <select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">
        SELECT
            orders.*,
            USER.username,
            USER.sex,
            USER.address,
            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> 
    
</mapper>

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

 

【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.User;

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<User> list=ordersMapperCustom.findUserAndItemsResultMap();
        
        System.out.println(list.size());
        
        sqlSession.close();
    }
}

【运行结果】

 

 【小结】

1.若要实现查询用户购买的商品信息明细清单(用户名、用户地址、购买商品名称、购买时间、购买商品数量)等等,

针对这个需求就可以使用resultType,将查询到的记录映射到一个扩展的pojo中,能方便实现。

2.一对多是多对对的特例,如下需求:

查询用户购买的商品信息,用户和商品的关系时多对多关系。

  2.1需求1:

查询字段:用户账号、用户名称、用户性别、商品名称、商品价格(常见的需求,常称为:用户购买商品明细列表)

方法:使用resultType将上边查询列映射到pojo输出。

  2.2需求2;

查询字段:用户账号、用户名称、购买商品数量、商品明细

方法;使用resultMap将用户购买的商品明细列表映射到user对象中。

 

记住:

使用resultMap是针对那些对查询结果映射有特殊要求的功能,比如特殊要求映射成的list中嵌套包括多个list。

 

推荐阅读