Mybatis学习笔记(4)-高级映射之一对多映射

1,780 阅读2分钟

MyBatis学习笔记(1)—使用篇

MyBatis学习笔记(2)—映射关系篇

MyBatis学习笔记(3)—高级映射之一对一映射

Mybatis学习笔记(4)-高级映射之一对多映射

Mybatis学习笔记(5)-高级映射之多对多映射 敬请期待...

这一节紧跟上一节MyBatis学习笔记(3)—高级映射之一对一映射,用的数据表也是一样的。回忆上一节的数据表,想想哪些表之间是一对多的关系。

很明显订单表(orders)和订单项(orderitems)是一对多的关系:

orders表的order_num是唯一的,但是同一个orders表可以对应多个orderitems,这些orderitemsorder_num都与对应的ordersorder_num一致。

首先准备查询的SQL语句:

SELECT o.*, oi.order_item, oi.prod_id, oi.quantity, oi.item_price
FROM orders AS o, orderitems AS oi
WHERE o.order_num=oi.order_num

如果按照上一节的套路,那首先应该讲解返回值使用resultType,但是如果返回值是resultType定义的POJO的话,那么无疑查询出来的POJO信息的前半段都会包含大量重复的订单信息,所以这时候我们最好返回resultMap,主要思路就是在Orders类中添加List orderitems属性,这样查询一个订单信息,它所包含的订单项也会反映在它的orderitems属性中。

所以此时的Orders包含以下属性:

public class Orders {
    private Integer orderNum;
    private Date orderDate;
    private Integer custId;
    private Customer customer;
    private List<OrderItems> orderItems;
    ...

定义ResultMap

因为上一节我们已经定义了OrdersCustomerResultMap,现在我们仅仅添加了一个orderItems属性,所以我们可以继承上一节的ResultMap,定义如下:

<resultMap id="OrderAndOrderItemsResultMap" type="com.shuqing28.pojo.Orders" extends="OrdersCustomerResultMap">
        <collection property="orderItems" ofType="com.shuqing28.pojo.OrderItems">
            <id column="order_num" property="orderNum" />
            <id column="order_item" property="orderItem"/>
            <result column="prod_id" property="prodId"/>
            <result column="quantity" property="quantity"/>
            <result column="item_price" property="itemPrice"/>
        </collection>
</resultMap>

因为添加的orderItems是一个List集合对象,所以这里用collection定义新元素,第一行最后extends也反映我们是继承的上一节的OrdersCustomerResultMap

定义select语句

由于继承了上一节的resultMap,所以我们的查询还是附带Customer信息,所以最终的SQL如下:

<select id="findOrderAndItemsMap" resultMap="OrderAndOrderItemsResultMap">
    SELECT o.order_num,o.order_date, c.*, oi.order_item, oi.prod_id, oi.quantity, oi.item_price
    FROM orders AS o, customers AS c, orderitems AS oi
    WHERE o.cust_id = c.cust_id
    AND o.order_num=oi.order_num
</select>

这样就是3表联查,也稍微扩充了下我们的场景。

当然我们还得在DAO类中声明接口

声明接口:

public List<Orders> findOrderAndItemsMap();

测试

 @Test
    public void findOrderAndItemsMap(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            OrdersDao ordersDao = sqlSession.getMapper(OrdersDao.class);
            List<Orders> orders = ordersDao.findOrderAndItemsMap();
            System.out.println(orders);
        } finally {
            sqlSession.close();
        }
    }

测试结果

可以发现orders还是有5个,查看第一个orders,包含了4个orderItems,然后具体的orderItems中的各个属性也是有值的。