引言
在数据库应用开发中,经常会遇到需要查询多个表之间的关联关系的情况。MyBatis是一个流行的Java持久层框架,它提供了灵活的配置方式来处理多表查询中的一对多、一对一和多对多关系。本文将介绍如何在MyBatis中配置和使用这些关联关系。
一、一对多关系配置
在数据库中,一对多关系是指一个表的一条记录对应另一个表的多条记录。在MyBatis中,我们可以通过以下步骤来配置和使用一对多关系:
- 创建实体类
首先,我们需要创建两个实体类,分别表示一对多关系中的一方和多方。例如,我们创建一个Order类和一个OrderItem类,其中一个订单可以对应多个订单项。
public class Order { private Long id; private String orderNo; private List<OrderItem> orderItems; // 省略getter和setter方法 } public class OrderItem { private Long id; private String productName; // 省略getter和setter方法 } package com.yuan.vo; import com.yuan.model.Order; import com.yuan.model.OrderItem; import java.util.ArrayList; import java.util.List; /** * @author 叶秋 * @site * @company 卓京公司 * @create 2023-09-01 11:48 */ public class OrderVO extends Order { private List<OrderItem> list = new ArrayList<>(); public List<OrderItem> getList() { return list; } public void setList(List<OrderItem> list) { this.list = list; } } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23 • 24 • 25 • 26 • 27 • 28 • 29 • 30 • 31 • 32 • 33 • 34 • 35 • 36 • 37 • 38 • 39 • 40
- 创建Mapper接口和XML文件
接下来,我们需要创建Mapper接口和对应的XML文件来定义查询方法和SQL语句。在XML文件中,我们可以使用MyBatis的标签来配置一对多关系。
<!-- OrderMapper.xml --> <mapper namespace="com.yuan.mapper.OrderMapper"> <resultMap id="OrderVoMap" type="com.yuan.vo.OrderVO" > <result column="order_id" property="orderId"></result> <result column="order_no" property="orderNo"></result> <collection property="list" ofType="com.yuan.model.OrderItem"> <result column="order_item_id" property="orderItemId"></result> <result column="product_id" property="productId"></result> <result column="quantity" property="quantity"></result> <result column="oid" property="oid"></result> </collection> </resultMap> <select id="demo1" resultMap="OrderVoMap" parameterType="java.lang.Integer" > select * from t_hibernate_order o ,t_hibernate_order_item oit where o.order_id = oit.oid and o.order_id = #{oid} </select> </mapper> • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22
- 编写查询方法
最后,我们在Mapper接口中定义查询方法,并在XML文件中配置对应的SQL语句。
package com.yuan.Biz; import com.yuan.vo.OrderVO; /** * @author 叶秋 * @site * @company 卓京公司 * @create 2023-09-01 13:08 */ public interface OrderBiz { OrderVO demo1(Integer oid); } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16
- 使用一对多关系查询
现在,我们可以在代码中使用一对多关系查询了。
package com.yuan.Biz.Impl; import com.yuan.Biz.OrderBiz; import com.yuan.vo.OrderVO; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author 叶秋 * @site * @company 卓京公司 * @create 2023-09-01 13:13 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:spring-context.xml"}) public class OrderBizImplTest { @Autowired private OrderBiz orderBiz; @Test public void demo1() { OrderVO orderVO = orderBiz.demo1(7); System.out.println(orderVO); orderVO.getList().forEach(System.out::println); } } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23 • 24 • 25 • 26 • 27 • 28 • 29 • 30 • 31 • 32
二、一对一关系配置
- 创建实体类
首先,我们需要创建两个实体类,分别表示一对多关系中的一方和一方。例如,我们创建一个Order类和一个OrderItem类,其中一个订单可以对应一个订单项。
public class Order { private Long id; private String orderNo; private List<OrderItem> orderItems; // 省略getter和setter方法 } public class OrderItem { private Long id; private String productName; // 省略getter和setter方法 } package com.yuan.vo; import com.yuan.model.Order; import com.yuan.model.OrderItem; /** * @author 叶秋 * @site * @company 卓京公司 * @create 2023-09-01 13:58 */ public class OrderItemVo extends OrderItem { private Order order; public Order getOrder() { return order; } public void setOrder(Order order) { this.order = order; } } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23 • 24 • 25 • 26 • 27 • 28 • 29 • 30 • 31 • 32 • 33 • 34 • 35 • 36 • 37 • 38
- 创建Mapper接口和XML文件
接下来,我们需要创建Mapper接口和对应的XML文件来定义查询方法和SQL语句。在XML文件中,我们可以使用MyBatis的标签来配置一对一关系。
<resultMap id="OrderItemVoMap" type="com.yuan.vo.OrderItemVo"> <result column="order_item_id" property="orderItemId"></result> <result column="product_id" property="productId"></result> <result column="quantity" property="quantity"></result> <result column="oid" property="oid"></result> <association property="order" javaType="com.yuan.model.Order"> <result column="order_id" property="orderId"></result> <result column="order_no" property="orderNo"></result> </association> </resultMap> <select id="demo2" resultMap="OrderItemVoMap" parameterType="java.lang.Integer" > select * from t_hibernate_order o ,t_hibernate_order_item oit where o.order_id = oit.oid and oit.order_item_id = #{oiid} </select> • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15
- 编写查询方法
最后,我们在Mapper接口中定义查询方法,并在XML文件中配置对应的SQL语句。
package com.yuan.Biz; import com.yuan.model.OrderItem; /** * @author 叶秋 * @site * @company 卓京公司 * @create 2023-09-01 14:03 */ public interface OrderItemBiz { OrderItem demo2( Integer oiid); } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16
- 使用一对一关系查询
现在,我们可以在代码中使用一对多关系查询了。
package com.yuan.Biz.Impl; import com.yuan.Biz.OrderItemBiz; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author 叶秋 * @site * @company 卓京公司 * @create 2023-09-01 14:06 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:spring-context.xml"}) public class OrderItemBizImplTest { @Autowired private OrderItemBiz orderItemBiz; @Test public void demo2() { System.out.println(orderItemBiz.demo2(27)); } } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23 • 24 • 25 • 26 • 27
三、多对多关系配置
在数据库中,多对多关系是指两个表之间存在多对多的关系。在MyBatis中,我们可以通过以下步骤来配置和使用多对多关系:
- 创建实体类
首先,我们需要创建两个实体类,分别表示多对多关系中的两个表。例如,我们创建一个User类和一个Role类,一个用户可以拥有多个角色,一个角色也可以被多个用户拥有。
package com.yuan.model; import lombok.ToString; @ToString public class HBook { private Integer bookId; private String bookName; private Float price; public HBook(Integer bookId, String bookName, Float price) { this.bookId = bookId; this.bookName = bookName; this.price = price; } public HBook() { super(); } public Integer getBookId() { return bookId; } public void setBookId(Integer bookId) { this.bookId = bookId; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public Float getPrice() { return price; } public void setPrice(Float price) { this.price = price; } } package com.yuan.model; import lombok.ToString; @ToString public class HBookCategory { private Integer bcid; private Integer bid; private Integer cid; public HBookCategory(Integer bcid, Integer bid, Integer cid) { this.bcid = bcid; this.bid = bid; this.cid = cid; } public HBookCategory() { super(); } public Integer getBcid() { return bcid; } public void setBcid(Integer bcid) { this.bcid = bcid; } public Integer getBid() { return bid; } public void setBid(Integer bid) { this.bid = bid; } public Integer getCid() { return cid; } public void setCid(Integer cid) { this.cid = cid; } } package com.yuan.model; import lombok.ToString; @ToString public class HCategory { private Integer categoryId; private String categoryName; public HCategory(Integer categoryId, String categoryName) { this.categoryId = categoryId; this.categoryName = categoryName; } public HCategory() { super(); } public Integer getCategoryId() { return categoryId; } public void setCategoryId(Integer categoryId) { this.categoryId = categoryId; } public String getCategoryName() { return categoryName; } public void setCategoryName(String categoryName) { this.categoryName = categoryName; } } package com.yuan.vo; import com.yuan.model.HBook; import com.yuan.model.HCategory; import java.util.List; /** * @author 叶秋 * @site * @company 卓京公司 * @create 2023-09-01 20:35 */ public class HbookVo extends HBook { private List<HCategory> categories ; public List<HCategory> getCategories() { return categories; } public void setCategories(List<HCategory> categories) { this.categories = categories; } } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23 • 24 • 25 • 26 • 27 • 28 • 29 • 30 • 31 • 32 • 33 • 34 • 35 • 36 • 37 • 38 • 39 • 40 • 41 • 42 • 43 • 44 • 45 • 46 • 47 • 48 • 49 • 50 • 51 • 52 • 53 • 54 • 55 • 56 • 57 • 58 • 59 • 60 • 61 • 62 • 63 • 64 • 65 • 66 • 67 • 68 • 69 • 70 • 71 • 72 • 73 • 74 • 75 • 76 • 77 • 78 • 79 • 80 • 81 • 82 • 83 • 84 • 85 • 86 • 87 • 88 • 89 • 90 • 91 • 92 • 93 • 94 • 95 • 96 • 97 • 98 • 99 • 100 • 101 • 102 • 103 • 104 • 105 • 106 • 107 • 108 • 109 • 110 • 111 • 112 • 113 • 114 • 115 • 116 • 117 • 118 • 119 • 120 • 121 • 122 • 123 • 124 • 125 • 126 • 127 • 128 • 129 • 130 • 131 • 132 • 133 • 134 • 135 • 136 • 137 • 138 • 139 • 140 • 141 • 142 • 143 • 144 • 145 • 146 • 147 • 148 • 149 • 150 • 151 • 152 • 153 • 154 • 155 • 156
- 创建Mapper接口和XML文件
接下来,我们需要创建Mapper接口和对应的XML文件来定义查询方法和SQL语句。在XML文件中,我们可以使用MyBatis的标签来配置多对多关系。
<resultMap id="HookVoMap" type="com.yuan.vo.HbookVo" > <result column="book_id" property="bookId"></result> <result column="book_name" property="bookName"></result> <result column="price" property="price"></result> <collection property="categories" ofType="com.yuan.model.HCategory"> <result column="category_id" property="categoryId"></result> <result column="category_name" property="categoryName"></result> </collection> </resultMap> <select id="demo3" resultMap="HookVoMap" parameterType="java.lang.Integer"> select * from t_hibernate_book b ,t_hibernate_book_category bc,t_hibernate_category c where b.book_id = bc.bid and bc.cid = c.category_id and b.book_id = #{bid} </select> • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20
- 编写查询方法
最后,我们在Mapper接口中定义查询方法,并在XML文件中配置对应的SQL语句。
package com.yuan.Biz.Impl; import com.yuan.Biz.HBookBiz; import com.yuan.mapper.HBookMapper; import com.yuan.vo.HbookVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @author 叶秋 * @site * @company 卓京公司 * @create 2023-09-01 21:23 */ @Service public class HBookBizImpl implements HBookBiz { @Autowired private HBookMapper hBookMapper; @Override public HbookVo demo3(Integer bid) { return hBookMapper.demo3(bid); } } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23 • 24 • 25 • 26 • 27 • 28
- 使用多对多关系查询
现在,我们可以在代码中使用多对多关系查询了。
package com.yuan.Biz.Impl; import com.yuan.Biz.HBookBiz; import com.yuan.vo.HbookVo; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author 叶秋 * @site * @company 卓京公司 * @create 2023-09-01 21:24 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:spring-context.xml"}) public class HBookBizImplTest { @Autowired private HBookBiz hBookBiz; @Test public void demo3() { HbookVo hbookVo = hBookBiz.demo3(8); System.out.println(hbookVo); hbookVo.getCategories().forEach(System.out::println); } } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23 • 24 • 25 • 26 • 27 • 28 • 29
总结
本文介绍了在MyBatis中配置和使用一对多和多对多关系的方法。通过合理的实体类设计、Mapper接口和XML文件的配置,我们可以方便地进行多表查询,并丰富了应用程序的功能和灵活性。
补充内容:在实际开发中,我们还可以使用MyBatis的动态SQL和缓存等特性来进一步优化查询性能和提高开发效率。希望本文对您在MyBatis中处理关联关系有所帮助。