• Mybatis的关系关联配置


    目录

    前言

    一. Mybatis关系关联配置的优劣

    1.1 MyBatis中的关系关联配置具有以下好处:

    1.2 然而,MyBatis中的关系关联配置也存在一些缺点:

    二. 关联关系的方向

    单向关联

    双向关联

    三. 一对一关联配置

    四. 一对多关联配置

    五. 多对多关联配置


    前言

    MyBatis是一个流行的Java持久化框架,它提供了一种简单而强大的方式来映射Java对象和关系数据库之间的数据。在MyBatis中,关系关联配置是一种用于定义对象之间关系的方式,它允许我们在查询数据库时同时获取相关联的对象。

    在MyBatis中,有三种主要的关系关联配置方式:一对一(One-to-One)、一对多(One-to-Many)和多对多(Many-to-Many)。

    一. Mybatis关系关联配置的优劣

    1.1 MyBatis中的关系关联配置具有以下好处:

    1. 简化数据查询:通过关系关联配置,可以在查询数据时自动加载相关联的数据,无需手动编写复杂的SQL语句。这简化了数据查询的过程,减少了开发人员的工作量。

    2. 提高代码可读性:通过关系关联配置,可以将数据表之间的关系直观地映射到Java对象中。这使得代码更易于理解和维护,提高了代码的可读性。

    3. 减少数据库访问次数:通过关系关联配置,可以一次性加载多个相关联的数据,减少了与数据库的交互次数。这可以提高系统的性能和响应速度。

    4. 支持对象导航:通过关系关联配置,可以在Java对象中直接访问相关联的数据,而无需手动编写额外的查询语句。这简化了代码的编写,提高了开发效率。

    1.2 然而,MyBatis中的关系关联配置也存在一些缺点:

    1. 学习成本较高:关系关联配置需要了解MyBatis的配置文件和相关标签的使用方法。对于初学者来说,可能需要花费一些时间来学习和理解这些配置。

    2. 配置复杂性:对于复杂的关系关联,配置文件可能会变得复杂和冗长。这可能增加了维护和调试的难度。

    3. 性能问题:如果关系关联配置不合理,可能会导致数据加载过多或过少,从而影响系统的性能。因此,在配置关系关联时需要注意性能优化的问题。

    二. 关联关系的方向

    在MyBatis中,关系关联的方向可以分为两种:单向关联和双向关联

    单向关联

    单向关联表示关系只在一个方向上存在,其中一个表可以关联到另一个表,但反过来不行。在单向关联中,只有一个表的对象包含了关联对象的引用,而关联对象本身不包含对关联表的引用。

    例如,假设我们有两个表:User和Order,一个用户可以有多个订单。在这种情况下,我们可以在User对象中定义一个关联属性List orders,表示一个用户关联多个订单。但是,在Order对象中并不包含对用户的引用。

    单向关联的配置在MyBatis中非常简单,只需要在中使用标签来定义关联即可。

    双向关联

    双向关联表示关系在两个表之间是相互关联的,每个表的对象都包含了对另一个表的引用。这样,我们可以通过一个表的对象访问到关联表的对象,也可以通过关联表的对象访问到原始表的对象。

    以前面的例子为例,我们可以在User对象中定义一个关联属性List orders,表示一个用户关联多个订单。同时,在Order对象中也定义一个关联属性User user,表示一个订单关联一个用户。

    双向关联的配置相对复杂一些,需要在中使用标签来定义关联,并在关联对象中使用标签来定义反向关联。

    需要注意的是,无论是单向关联还是双向关联,都需要在MyBatis的映射文件中进行配置。关联的方向取决于我们在配置时定义的关联属性和关联对象的引用。

    总结来说,MyBatis中的关系关联可以是单向关联或双向关联。单向关联表示关系只在一个方向上存在,而双向关联表示关系在两个表之间是相互关联的。在配置关系关联时,我们需要定义关联属性和关联对象的引用,以确定关联的方向。

    三. 一对一关联配置

    一对一关联配置用于表示两个对象之间的一对一关系(例如夫妻关系,人与身份证)。在数据库中,这通常通过外键来实现。在MyBatis中,我们可以使用元素来配置一对一关联。该元素通常嵌套在元素中,并使用property属性指定关联对象的属性名。

    以订单表(order)和订单项表(orderItem)为例,一个订单项对应一个订单。

    编写一个vo类继承orderItem,在映射文件中可以通过这个类拿到订单表和订单项表的每个属性:

    1. package com.xissl.vo;
    2. import com.xissl.model.HOrder;
    3. import com.xissl.model.HOrderItem;
    4. /**
    5. * @author xissl
    6. * @create 2023-09-04 9:52
    7. */
    8. public class OrderItemVo extends HOrderItem {
    9. private HOrder horder;
    10. public HOrder getHorder() {
    11. return horder;
    12. }
    13. public void setHorder(HOrder horder) {
    14. this.horder = horder;
    15. }
    16. }

     在映射文件中配置一对一关联,HOrderItemMapper.xml

    1. "OrderItemVoMap" type="com.xissl.vo.OrderItemVo">
    2. "order_item_id" property="orderItemId">
    3. "product_id" property="productId">
    4. "quantity" property="quantity">
    5. "oid" property="oid">
    6. "horder" javaType="com.xissl.model.HOrder">
    7. "order_id" property="orderId">
    8. "order_no" property="orderNo">

    在上面的示例中,我们首先定义了一个resultMap,用于映射OrderItem对象和Order对象之间的关系。在resultMap中,我们使用association元素来配置一对一关联。association元素中的property属性指定了在OrderItem对象中表示Order对象的属性名,javaType属性指定了关联对象的类型。

    然后,我们定义了一个查询语句selectByOrderItemId,使用resultMap来映射查询结果。

     编写mapper层接口:

    OrderItemVo selectByOrderItemId(@Param("orderItemId") Integer orderItemId);

     业务逻辑层:

    1. package com.xissl.biz;
    2. import com.xissl.model.HOrderItem;
    3. import com.xissl.vo.OrderItemVo;
    4. import org.apache.ibatis.annotations.Param;
    5. public interface HOrderItemBiz {
    6. OrderItemVo selectByOrderItemId(Integer orderItemId);
    7. }

    实现业务层接口:

    1. package com.xissl.biz.impl;
    2. import com.xissl.biz.HOrderItemBiz;
    3. import com.xissl.mapper.HOrderItemMapper;
    4. import com.xissl.vo.OrderItemVo;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Service;
    7. /**
    8. * @author xissl
    9. * @create 2023-09-04 9:59
    10. */
    11. @Service
    12. public class HOrderItemBizImpl implements HOrderItemBiz {
    13. @Autowired
    14. private HOrderItemMapper hOrderItemMapper;
    15. @Override
    16. public OrderItemVo selectByOrderItemId(Integer orderItemId) {
    17. return hOrderItemMapper.selectByOrderItemId(orderItemId);
    18. }
    19. }

      测试代码及结果:

    1. package com.xissl.biz.impl;
    2. import com.xissl.biz.HOrderItemBiz;
    3. import com.xissl.vo.OrderItemVo;
    4. import org.junit.Test;
    5. import org.junit.runner.RunWith;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.test.context.ContextConfiguration;
    8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    9. import static org.junit.Assert.*;
    10. /**
    11. * @author xissl
    12. * @create 2023-09-04 10:01
    13. */
    14. @RunWith(SpringJUnit4ClassRunner.class)
    15. @ContextConfiguration(locations={"classpath:spring-context.xml"})
    16. public class HOrderItemBizImplTest {
    17. @Autowired
    18. private HOrderItemBiz hOrderItemBiz;
    19. @Test
    20. public void selectByOrderItemId() {
    21. OrderItemVo orderItemVo = hOrderItemBiz.selectByOrderItemId(27);
    22. System.out.println(orderItemVo);
    23. System.out.println(orderItemVo.getHorder());
    24. }
    25. }

    四. 一对多关联配置

    一对多关联配置用于表示一个对象与多个相关对象之间的关系(例如用户与用户的订单,锁和钥匙)。在数据库中,这通常通过外键来实现。在MyBatis中,我们可以使用元素来配置一对多关联。该元素通常嵌套在元素中,并使用property属性指定关联对象的属性名。

    以订单表(order)和订单项表(orderItem)为例,一个订单可以有多个订单项。

    编写一个vo类继承order,在映射文件中可以通过这个类拿到订单表和订单项表的每个属性:

    1. package com.xissl.vo;
    2. import com.xissl.model.HOrder;
    3. import com.xissl.model.HOrderItem;
    4. import java.util.ArrayList;
    5. import java.util.List;
    6. /**
    7. * @author xissl
    8. * @create 2023-09-04 8:49
    9. */
    10. public class OrderVo extends HOrder {
    11. private List orderItems = new ArrayList<>();
    12. public List getOrderItems() {
    13. return orderItems;
    14. }
    15. public void setOrderItems(List orderItems) {
    16. this.orderItems = orderItems;
    17. }
    18. }

    在映射文件中配置一对多关联,HOrderMapper.xml

    1. "OrderVoMap" type="com.xissl.vo.OrderVo" >
    2. "order_id" property="orderId">
    3. "order_no" property="orderNo">
    4. "orderItems" ofType="com.xissl.model.HOrderItem">
    5. "order_item_id" property="orderItemId">
    6. "product_id" property="productId">
    7. "quantity" property="quantity">
    8. "oid" property="oid">

    在上面的示例中,我们首先定义了一个resultMap,用于映射Order对象和OrderItem对象之间的关系。在resultMap中,我们使用collection元素来配置一对多关联。collection元素中的property属性指定了在Order对象中表示订单项表的属性名,ofType属性指定了关联对象的类型。

    然后,我们定义了一个查询语句selectByOid,使用resultMap来映射查询结果。

    编写mapper层接口:

        OrderVo selectByOid(@Param("oid") Integer oid);

     业务逻辑层:

     OrderVo selectByOid(Integer oid);

     实现业务层接口:

    1. package com.xissl.biz.impl;
    2. import com.xissl.biz.HOrderBiz;
    3. import com.xissl.mapper.HOrderMapper;
    4. import com.xissl.vo.OrderVo;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Service;
    7. /**
    8. * @author xissl
    9. * @create 2023-09-04 9:08
    10. */
    11. @Service
    12. public class HOrderBizImpl implements HOrderBiz {
    13. @Autowired
    14. private HOrderMapper hOrderMapper;
    15. @Override
    16. public OrderVo selectByOid(Integer oid) {
    17. return hOrderMapper.selectByOid(oid);
    18. }
    19. }

     测试代码及结果:

    1. package com.xissl.biz.impl;
    2. import com.xissl.biz.HOrderBiz;
    3. import com.xissl.vo.OrderVo;
    4. import org.junit.Test;
    5. import org.junit.runner.RunWith;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.test.context.ContextConfiguration;
    8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    9. import static org.junit.Assert.*;
    10. /**
    11. * @author xissl
    12. * @create 2023-09-04 9:10
    13. */
    14. @RunWith(SpringJUnit4ClassRunner.class)
    15. @ContextConfiguration(locations={"classpath:spring-context.xml"})
    16. public class HOrderBizImplTest {
    17. @Autowired
    18. private HOrderBiz hOrderBiz;
    19. @Test
    20. public void selectByOid() {
    21. OrderVo orderVo = hOrderBiz.selectByOid(7);
    22. System.out.println(orderVo);
    23. orderVo.getOrderItems().forEach(System.out::println);
    24. }
    25. }

    五. 多对多关联配置

    多对多关联配置用于表示两个对象之间的多对多关系(例如老师和学生)。在数据库中,这通常通过中间表来实现。在MyBatis中,我们可以使用元素来配置多对多关联。该元素通常嵌套在元素中,并使用property属性指定关联对象的属性名。

    多对多关系就是和一对多的关系的大同小异,只是多对多的关系可以看成两个一对多关系。

    vo类 BookVo:

    1. package com.xissl.vo;
    2. import com.xissl.model.HBook;
    3. import com.xissl.model.HCategory;
    4. import java.util.List;
    5. /**
    6. * @author xissl
    7. * @create 2023-09-04 10:43
    8. */
    9. public class HBookVo extends HBook {
    10. private List categories;
    11. public List getCategories() {
    12. return categories;
    13. }
    14. public void setCategories(List categories) {
    15. this.categories = categories;
    16. }
    17. }

    CategoryVo:

    1. package com.xissl.vo;
    2. import com.xissl.model.HBook;
    3. import com.xissl.model.HCategory;
    4. import java.util.ArrayList;
    5. import java.util.List;
    6. /**
    7. * @author xissl
    8. * @create 2023-09-04 11:03
    9. */
    10. public class CategroyVo extends HCategory {
    11. private List hbooks = new ArrayList<>();
    12. public List getHbooks() {
    13. return hbooks;
    14. }
    15. public void setHbooks(List hbooks) {
    16. this.hbooks = hbooks;
    17. }
    18. }

    映射文件 HBookMapper.xml

    1. "HBookVoMap" type="com.xissl.vo.HBookVo">
    2. "book_id" property="bookId">
    3. "book_name" property="bookName">
    4. "price" property="price">
    5. "categories" ofType="com.xissl.model.HCategory">
    6. "category_id" property="categoryId">
    7. "category_name" property="categoryName">

    HCategoryMapper.xml 

    1. "CategoryVoMap" type="com.xissl.vo.CategroyVo">
    2. "category_id" property="categoryId">
    3. "category_name" property="categoryName">
    4. "hbooks" ofType="com.xissl.model.HBook">
    5. "book_id" property="bookId">
    6. "book_name" property="bookName">
    7. "price" property="price">

     mapper层接口 BookMapper:

        HBookVo selectByBid(@Param("bid") Integer bid);

    CategoryMapper 

        HBookVo selectByBid(@Param("bid") Integer bid);

    业务逻辑层:

        HBookVo selectByBid(Integer bid);

        CategroyVo selectByCategroyId(Integer cid);

     实现业务层 BookBiz

    1. package com.xissl.biz.impl;
    2. import com.xissl.biz.HBookBiz;
    3. import com.xissl.mapper.HBookMapper;
    4. import com.xissl.vo.HBookVo;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Service;
    7. /**
    8. * @author xissl
    9. * @create 2023-09-04 10:55
    10. */
    11. @Service
    12. public class HBookBizImpl implements HBookBiz {
    13. @Autowired
    14. private HBookMapper hBookMapper;
    15. @Override
    16. public HBookVo selectByBid(Integer bid) {
    17. return hBookMapper.selectByBid(bid);
    18. }
    19. }

    实现CategoryBiz

    1. package com.xissl.biz.impl;
    2. import com.xissl.biz.HCategoryBiz;
    3. import com.xissl.mapper.HCategoryMapper;
    4. import com.xissl.vo.CategroyVo;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Service;
    7. /**
    8. * @author xissl
    9. * @create 2023-09-04 11:11
    10. */
    11. @Service
    12. public class HCategoryBizImpl implements HCategoryBiz {
    13. @Autowired
    14. private HCategoryMapper hCategoryMapper;
    15. @Override
    16. public CategroyVo selectByCategroyId(Integer cid) {
    17. return hCategoryMapper.selectByCategroyId(cid);
    18. }
    19. }

     测试代码及结果:

    1. package com.xissl.biz.impl;
    2. import com.xissl.biz.HBookBiz;
    3. import com.xissl.vo.HBookVo;
    4. import org.junit.Test;
    5. import org.junit.runner.RunWith;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.test.context.ContextConfiguration;
    8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    9. import static org.junit.Assert.*;
    10. /**
    11. * @author xissl
    12. * @create 2023-09-04 10:56
    13. */
    14. @RunWith(SpringJUnit4ClassRunner.class)
    15. @ContextConfiguration(locations={"classpath:spring-context.xml"})
    16. public class HBookBizImplTest {
    17. @Autowired
    18. private HBookBiz hBookBiz;
    19. @Test
    20. public void selectByBid() {
    21. HBookVo hBookVo = hBookBiz.selectByBid(8);
    22. System.out.println(hBookVo);
    23. hBookVo.getCategories().forEach(System.out::println);
    24. }
    25. }

    1. package com.xissl.biz.impl;
    2. import com.xissl.biz.HCategoryBiz;
    3. import com.xissl.vo.CategroyVo;
    4. import org.junit.Test;
    5. import org.junit.runner.RunWith;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.test.context.ContextConfiguration;
    8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    9. import static org.junit.Assert.*;
    10. /**
    11. * @author xissl
    12. * @create 2023-09-04 11:12
    13. */
    14. @RunWith(SpringJUnit4ClassRunner.class)
    15. @ContextConfiguration(locations={"classpath:spring-context.xml"})
    16. public class HCategoryBizImplTest {
    17. @Autowired
    18. private HCategoryBiz hCategoryBiz;
    19. @Test
    20. public void selectByCategroyId() {
    21. CategroyVo categroyVo = hCategoryBiz.selectByCategroyId(8);
    22. System.out.println(categroyVo);
    23. categroyVo.getHbooks().forEach(System.out::println);
    24. }
    25. }

    除了上述关系关联配置方式,MyBatis还提供了其他一些配置选项,如延迟加载(Lazy Loading)和级联操作(Cascade)。延迟加载允许我们在需要时才加载关联对象的数据,而级联操作允许我们在操作主对象时同时操作关联对象。

    总结起来,MyBatis中的关系关联配置提供了一种灵活而强大的方式来处理对象之间的关系。通过合理配置关系关联,我们可以轻松地进行复杂的数据库查询和操作。

  • 相关阅读:
    Linux从入门到精通(十一)——计划任务
    pyinstaller 打包pyqt6等ui文件为exe可执行程序的方法
    STM32F103学习笔记(六) RTC实时时钟(应用篇)
    【Python安全攻防】【网络安全】一、常见被动信息搜集手段
    Linux安装rabbitMq(亲测可用)解决只能本地访问的问题
    网络编程套接字,Linux下实现echo服务器和客户端
    Centos批量删除系统重复进程
    Programming Assignment 3COVID Testing
    SpringBoot整合Shiro
    局域网基本概念和体系结构
  • 原文地址:https://blog.csdn.net/lijie1025/article/details/132509084