4.4Java EE——多对多查询

订单和商品多对多关系图

         在实际项目开发中,多对多的关联关系非常常见。以订单和商品为例,一个订单可以包含多种商品,而一种商品又可以属于多个订单,订单和商品属于多对多关联关系,订单和商品之间的关联关系如图。

        在数据库中,多对多的关联关系通常使用一个中间表来维护,中间表中的订单id作为外键关联订单表的id,中间表中的商品id作为外键关联商品表的id。这三个表之间的关系如图。

下面以订单表与商品表之间的多对多关系为例,讲解如何使用MyBatis处理多对多的关系

  1. 在名为mybatis的数据库中创建名称为tb_product的商品表和名称为tb_ordersitem 的中间表,同时在表中预先插入几条数据。
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.0');

# 创建一个名称为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));

INSERT INTO tb_ordersitem VALUES ('1', '1', '1');

INSERT INTO tb_ordersitem VALUES ('2', '1', '3');

INSERT INTO tb_ordersitem VALUES ('3', '3', '3');

2、创建持久化类Product,并在类中定义商品id、商品名称、商品单价等属性,以及与订单关联的属性。

public class Product {

    private Integer 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 + "]";}

}

3、在商品持久化类中,除了需要添加订单的集合属性外,还需要在订单持久化类(Orders.java)中增加商品集合的属性及其对应的getter/setter方法,Orders类中添加的代码如下。

// 关联商品集合属性

private List<Product> productList;

// 省略getter/setter方法,以及重写的toString()方法

4、创建订单实体映射文件OrdersMapper.xml,用于编写订单信息的查询SQL语句,并在映射文件中编写多对多关联映射查询的配置信息。

<mapper namespace="com.mac.mapper.OrdersMapper">

   <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.mac.mapper.ProductMapper.findProductById" ></collection>

</resultMap>

</mapper>

5、创建商品实体映射文件ProductMapper.xml,用于编写订单与商品信息的关联查询SQL语句。 

<mapper namespace="com.mac.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>

6、将新创建的映射文件OrdersMapper.xml和ProductMapper.xml的文件路径配置到核心配置文件mybatis-config.xml中。

<mapper resource="com/mac/mapper/OrdersMapper.xml" />

<mapper resource="com/mac/mapper/ProductMapper.xml" />

7、在测试类MyBatisTest中,编写多对多关联查询的测试方法findOrdersTest()。

public void findOrdersTest() {

    // 1.生成SqlSession对象

    SqlSession session = MyBatisUtils.getSession(); 

    // 2.查询id为1的订单中的商品信息

    Orders orders = session.selectOne("com.mac.mapper."

                           + "OrdersMapper.findOrdersWithPorduct", 1);

    System.out.println(orders);// 3.输出查询结果信息

    session.close();// 4.关闭SqlSession

}

8、查询订单及关联商品的另一方式

        除了使用嵌套查询的方式查询订单及其关联的商品信息外,还可以在OrdersMapper.xml中使用嵌套结果的方式进行查询。

猜你喜欢

转载自blog.csdn.net/W_Fe5/article/details/131564009