在进行数据库原理的时候,我们将E-R图的实体转化为我们的表时,有时要考虑到多对多的关系。比如下图:
我们可以转化为下面的表:
因为User和Orders是1:n的关系,所以Orders有一个外键。
t_orders表
id | number | user_id(外键) |
1 | 111111111 | 1 |
2 | 111111112 | 1 |
3 | 111111113 | 1 |
4 | 111111114 | 2 |
因为多对多关系需要一个额外的表来辅助:
t_ordersitem表
id | orders_id | product_id |
1 | 1 | 1 |
2 | 1 | 2 |
3 | 1 | 3 |
4 | 2 | 2 |
5 | 3 | 1 |
t_product表
id | name | price |
1 | 香蕉 | 8.8 |
2 | 苹果 | 15 |
3 | 梨 | 9 |
我们知道,一个订单中可以都多个种类的水果,同一种类的水果也可以在不同的订单中。
我们现在的需求是,根据订单的id,查询出订单信息的同时,还要查出其包含的水果。(原来如果只按照id查询智,那么只会查出来id和编号number)。
第一步创建POJO类
public class Orders {
private Integer id;
private String number;
private List<Product> productList; //这个是为了,当查询Orders时,结果中嵌套包含的水果
//......
}
public class Product {
private Integer id;
private String name;
private Double price;
private List<Orders> ordersList; //这个是为了后期,想实现“根据水果的id,查看有哪些订单包含了这个产品”
// ......
}
第二步,编写.xml映射文件
方法一,一条SQL查完
<select id="findOrdersWithProduct1" parameterType="Integer" resultMap="OrdersWithProduct1">
SELECT o.*,p.id as pid ,p.name,p.price
FROM t_orders o,t_product p,t_ordersitem oi
where o.id=#{id} and oi.orders_id=o.id and oi.product_id=p.id
</select>
<resultMap id="OrdersWithProduct1" type="Orders">
<id property="id" column="id"></id>
<result property="number" column="number"></result>
<collection property="productList" ofType="Product">
<id property="id" column="pid"></id>
<result property="name" column="name"></result>
<result property="price" column="price"></result>
</collection>
</resultMap>
注意:我们<select>标签嵌套的SQL查询的结果如下(这里我们将#{id}替换为了1):
然后我们仔细观察,结果中Orders(id,number,user_id)=(1,111111111,1)这个是我们要查的type="Orders"这个类型抽象出来的一个对象,但是查出来有重复的多条记录。<collection>会将重复的这个自动封装为一个Orders对象。然后是将后面要嵌套的对象进行映射。
第三步,引入映射文件到配置文件
在mybatus-config核心配置文件的<mappers>下引入:
<mapper resource="mapper/OrdersMapper.xml"></mapper>
第四步测试
方法二,嵌套SQL查询
<select id="findOrdersWithProduct" parameterType="Integer" resultMap="OrdersWithProduct">
select *
from t_orders
where id = #{id}
</select>
<resultMap id="OrdersWithProduct" type="Orders">
<id property="id" column="id"></id>
<result property="number" column="number"></result>
<collection property="productList" column="id" ofType="Product" select="com.cupk.mapper.ProductMapper.findProductByOid"></collection>
</resultMap>
首先编写查找“主类-Orders”的SQL语句,然后再用<collection>进行查询,这里的column="id"的意思是将上面SQL中接受的id,传给后面的select=的语句。
<mapper namespace="com.cupk.mapper.ProductMapper">
<select id="findProductByOid" parameterType="Integer" resultType="Product">
SELECT * from t_product WHERE id in (SELECT product_id from t_ordersitem WHERE orders_id=#{id})
</select>
</mapper>
注意:这里也是嵌套查询。