• MyBatis的关联映射,resultMap元素之collection子元素,实现多对多关联关系(节选自:Java EE企业级应用开发教程)


    MyBatis映射文件中的<resultMap>元素中,包含一个<collection>子元素,MyBatis通过它来处理多对多关联关系。

    <collection>子元素的大部分属性与<association>子元素相同,但其还包含一个特殊属性——ofType。ofType属性与javaType属性对应,它用于指定实体对象中集合类属性所包含的元素类型。

    本文是MyBatis的关联映射,resultMap元素之association子元素,实现一对一关联关系(节选自:Java EE企业级应用开发教程)MyBatis的关联映射,resultMap元素之collection子元素,实现一对多关联关系(节选自:Java EE企业级应用开发教程)两篇文章的延续,如有配置上的问题,请参考上两篇文章。

    情景:在实际项目开发中,多对多的关联关系是非常觉的。以订单和商品为例,一个订单可以包含多种商品,而一种商品又可以属于多个订单,订单和商品就属于多对多的关联关系。

    一、创建数据结构及插入数据(MySQL),注意:请先选择数据库

    # 创建一个名称为tb_product的表
    CREATE TABLE tb_product(
        id INT(32) PRIMARY KEY AUTO_INCREMENT,
        name VARCHAR(32),
        price DOUBLE
    );
    
    # 插入3条数据
    INSERT INTO tb_product VALUES ('1','Java基础入门','44.5');
    INSERT INTO tb_product VALUES ('2','Java Web程序开发入门','38.5');
    INSERT INTO tb_product VALUES ('3','SSM框架整合实战','50');
    
    # 创建一个名称为tb_ordersitem 的中间表
    CREATE TABLE tb_ordersitem(
        id INT(32) PRIMARY KEY AUTO_INCREMENT,
        orders_id INT(32),
        product_id INT(32),
        FOREIGN KEY(orders_id) REFERENCES tb_orders(id),
        FOREIGN KEY(product_id) REFERENCES tb_product(id)
        );
    
    # 插入5条数据
    INSERT INTO tb_ordersitem VALUES ('1','1','1');
    INSERT INTO tb_ordersitem VALUES ('2','1','3');
    INSERT INTO tb_ordersitem VALUES ('3','3','1');
    INSERT INTO tb_ordersitem VALUES ('4','3','2');
    INSERT INTO tb_ordersitem VALUES ('5','3','3');

    二、创建实体类Product,并修改Orders实体类 

    package com.itheima.po;
    import java.util.List;
    /**
     * 商品持久化类
     */
    public class Product {
        private Integer id;  //商品id
        private String name; //商品名称
        private Double price;//商品单价
        private List<Orders> orders; //与订单的关联属性
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Double getPrice() {
            return price;
        }
        public void setPrice(Double price) {
            this.price = price;
        }
        public List<Orders> getOrders() {
            return orders;
        }
        public void setOrders(List<Orders> orders) {
            this.orders = orders;
        }
        @Override
        public String toString() {
            return "Product [id=" + id + ", name=" + name 
                               + ", price=" + price + "]";
        }
    }
    package com.itheima.po;
    
    import java.util.List;
    
    /**
     * 订单持久化类
     */
    public class Orders {
        private Integer id;    //订单id
        private String number;//订单编号
        //关联商品集合信息
        private List<Product> productList;
    
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getNumber() {
            return number;
        }
        public void setNumber(String number) {
            this.number = number;
        }
        public List<Product> getProductList() {
            return productList;
        }
        public void setProductList(List<Product> productList) {
            this.productList = productList;
        }
        @Override
        public String toString() {
            return "Orders [id=" + id + ", number=" + number + ", productList=" + productList + "]";
        }
    }

    三、创建映射文件ProductMapper.xml、OrdersMapper.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="com.itheima.mapper.ProductMapper">
        <select id="findProductById" parameterType="Integer" 
                                           resultType="Product">
            SELECT * from tb_product where id IN(
               SELECT product_id FROM tb_ordersitem  WHERE orders_id = #{id}
            )
        </select>
    </mapper>
    <?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="com.itheima.mapper.OrdersMapper">
        <!-- 多对多嵌套查询:通过执行另外一条SQL映射语句来返回预期的特殊类型 -->
        <select id="findOrdersWithPorduct" parameterType="Integer" 
                  resultMap="OrdersWithProductResult">
            select * from tb_orders WHERE id=#{id}    
        </select>
        <resultMap type="Orders" id="OrdersWithProductResult">
            <id property="id" column="id" />
            <result property="number" column="number" />
            <collection property="productList" column="id" ofType="Product" 
                 select="com.itheima.mapper.ProductMapper.findProductById">
            </collection>
        </resultMap>
        
        <!-- 多对多嵌套结果查询:查询某订单及其关联的商品详情 -->
        <select id="findOrdersWithPorduct2" parameterType="Integer" 
                 resultMap="OrdersWithPorductResult2">
            select o.*,p.id as pid,p.name,p.price
            from tb_orders o,tb_product p,tb_ordersitem  oi
            WHERE oi.orders_id=o.id 
            and oi.product_id=p.id 
            and o.id=#{id}
        </select>
        <!-- 自定义手动映射类型 -->
        <resultMap type="Orders" id="OrdersWithPorductResult2">
            <id property="id" column="id" />
            <result property="number" column="number" />
            <!-- 多对多关联映射:collection -->
            <collection property="productList" ofType="Product">
                <id property="id" column="pid" />
                <result property="name" column="name" />
                <result property="price" column="price" />
            </collection>
        </resultMap>
    </mapper>

    四、修改MyBatis配置文件(mybatis-config.xml),加入如下内容: 

             <mapper resource="com/itheima/mapper/OrdersMapper.xml" />
             <mapper resource="com/itheima/mapper/ProductMapper.xml" />

    五、修改测试程序MybatisAssociatedTest.java,加入如下内容:

    可以将findOrdersWithPorduct修改为findOrdersWithPorduct2,其输出仍然是一样的。

        /**
         * 多对多
         */
        @Test
        public void findOrdersTest(){
            // 1、通过工具类生成SqlSession对象
            SqlSession session = MybatisUtils.getSession();
            // 2、查询id为1的订单中的商品信息
            Orders orders = session.selectOne("com.itheima.mapper."
                                   + "OrdersMapper.findOrdersWithPorduct", 3);
            // 3、输出查询结果信息
            System.out.println(orders);
            // 4、关闭SqlSession
            session.close();
        }

    六、运行结果 

    DEBUG [main] - ==>  Preparing: select * from tb_orders WHERE id=? 
    DEBUG [main] - ==> Parameters: 3(Integer)
    DEBUG [main] - <==      Total: 1
    DEBUG [main] - ==>  Preparing: SELECT * from tb_product where id IN( SELECT product_id FROM tb_ordersitem WHERE orders_id = ? ) 
    DEBUG [main] - ==> Parameters: 3(Integer)
    DEBUG [main] - <==      Total: 3
    Orders [id=3, number=1000013, productList=[Product [id=1, name=Java基础入门, price=44.5], Product [id=2, name=Java Web程序开发入门, price=38.5], Product [id=3, name=SSM框架整合实战, price=50.0]]]
  • 相关阅读:
    十一作业
    11.20
    11.13 第十二次、
    11.13 第十一次、
    11.06第十次、
    11.06第九次、
    10.30
    10.23
    10.16
    10.9
  • 原文地址:https://www.cnblogs.com/nayitian/p/15162064.html
Copyright © 2020-2023  润新知