Mybatis的关联关系-多对多
在进行数据库原理的时候,我们将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.priceFROM t_orders o,t_product p,t_ordersitem oiwhere 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_orderswhere 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>
注意:这里也是嵌套查询。