• Myvatis关联关系映射与表对象之间的关系


    目录

    一、关联关系映射

    1.1 一对一

    1.2 一对多

     1.3 多对多

    二、处理关联关系的方式

    2.1 嵌套查询

    2.2 嵌套结果

    三、一对一关联映射

    3.1 建表

    ​编辑 3.2 配置文件

    3.3 代码生成

    3.4 编写测试

     四、一对多关联映射

    五、多对多关联映射

    六、小结 


    一、关联关系映射

    MyBatis是一款优秀的持久层框架,它提供了强大的关联关系映射能力。在MyBatis中,我们可以使用XML或注解来定义关联关系映射。

    1.1 一对一

    一对一关联映射:

    • 在XML中,我们可以使用元素来定义一对一关联映射,可以通过来指定关联对象的映射规则。
    • 注解中,可以使用@One注解来定义一对一关联映射。

    1.2 一对多

    一对多关联映射:

    • 在XML中,我们可以使用元素来定义一对多关联映射,可以通过来指定关联对象集合的映射规则。
    • 注解中,可以使用@Many注解来定义一对多关联映射

     1.3 多对多

    多对多关联映射:

    • 在XML中,我们可以使用元素来定义多对多关联映射,可以通过来指定中间表关联对象的映射规则。
    • 注解中,可以使用@Many注解来定义多对多关联映射

    同时,MyBatis还提供了一些常见的关联关系映射的配置选项,例如延迟加载、级联操作等,可以根据具体需求进行配置。

    总的来说,MyBatis的关联关系映射定义非常灵活,可以根据需求使用XML或注解来进行配置,提供了丰富的选项来满足不同场景下的需求。 

    二、处理关联关系的方式

    在MyBatis中,处理关联关系的方式主要有两种:嵌套查询嵌套结果

    2.1 嵌套查询

    嵌套查询(Nested Selects):

    这种方式是通过在SQL语句中使用子查询来实现关联查询。我们可以使用元素来配置关联关系。例如,在一个订单表中,可以通过子查询查询与订单相关的用户信息。

    2.2 嵌套结果

    嵌套结果(Nested Results):

    这种方式是通过在查询结果中嵌套关联对象的结果集来实现关联查询。我们可以使用元素中的元素来配置关联关系。例如,在一个订单表和订单项表的关系中,可以将订单项作为订单对象的一个属性。 

    关联查询的处理方式取决于具体的需求和数据模型嵌套查询适用于复杂的关联关系和需要在各部分之间添加额外条件的情况,而嵌套结果适用于简单的关联关系和需要携带完整对象信息的情况

    无论使用哪种方式,MyBatis都提供了灵活的配置选项来满足各种关联查询需求。使用MyBatis的关联映射机制,我们可以轻松地处理对象之间的关系,并在数据库操作中提供更强大的功能和效率。 

    三、一对一关联映射

    3.1 建表

    创建名为 t_hibernate_book (书籍表) 数据表

    创建名为 t_hibernate_book_category (书籍类别表) 数据表

    其中名为 bid 的属性字段为 t_hibernate_book (书籍表) 的 bid(主键) 的外键

    其中名为 cid 的属性字段为 t_hibernate_category (类别表) 的 category_id (主键) 的外键 

    创建名为 t_hibernate_category (类别表) 数据表 

    创建名为 t_hibernate_order (订单表) 数据表 

    创建名为 t_hibernate_order_item (订单详情表) 数据表

    其中名为 order_id 的属性字段为 t_hibernate_order (订单表) 的 oid (主键) 的外键

     3.2 配置文件

    修改名为 generatorConfig.xml 的 配置文件,修改后的所有代码如下 : 

    1. "1.0" encoding="UTF-8" ?>
    2. generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
    3. "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
    4. <generatorConfiguration>
    5. <properties resource="jdbc.properties"/>
    6. <classPathEntry location="D:\\temp2\\mvn_repository\\mysql\\mysql-connector-java\\5.1.44\\mysql-connector-java-5.1.44.jar"/>
    7. <context id="infoGuardian">
    8. <commentGenerator>
    9. <property name="suppressAllComments" value="true"/>
    10. <property name="suppressDate" value="true"/>
    11. commentGenerator>
    12. <jdbcConnection driverClass="${jdbc.driver}"
    13. connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/>
    14. <javaTypeResolver>
    15. <property name="forceBigDecimals" value="false"/>
    16. javaTypeResolver>
    17. <javaModelGenerator targetPackage="com.Kissship.model"
    18. targetProject="src/main/java">
    19. <property name="enableSubPackages" value="false"/>
    20. <property name="constructorBased" value="true"/>
    21. <property name="trimStrings" value="false"/>
    22. <property name="immutable" value="false"/>
    23. javaModelGenerator>
    24. <sqlMapGenerator targetPackage="com.Kissship.mapper"
    25. targetProject="src/main/java">
    26. <property name="enableSubPackages" value="false"/>
    27. sqlMapGenerator>
    28. <javaClientGenerator targetPackage="com.Kissship.mapper"
    29. targetProject="src/main/java" type="XMLMAPPER">
    30. <property name="enableSubPackages" value="false"/>
    31. javaClientGenerator>
    32. <table schema="" tableName="t_hibernate_book" domainObjectName="HBook"
    33. enableCountByExample="false" enableDeleteByExample="false"
    34. enableSelectByExample="false" enableUpdateByExample="false">
    35. table>
    36. <table schema="" tableName="t_hibernate_category" domainObjectName="Category"
    37. enableCountByExample="false" enableDeleteByExample="false"
    38. enableSelectByExample="false" enableUpdateByExample="false">
    39. table>
    40. <table schema="" tableName="t_hibernate_book_category" domainObjectName="HBookCategory"
    41. enableCountByExample="false" enableDeleteByExample="false"
    42. enableSelectByExample="false" enableUpdateByExample="false">
    43. table>
    44. <table schema="" tableName="t_hibernate_order" domainObjectName="Order"
    45. enableCountByExample="false" enableDeleteByExample="false"
    46. enableSelectByExample="false" enableUpdateByExample="false">
    47. table>
    48. <table schema="" tableName="t_hibernate_order_item" domainObjectName="OrderItem"
    49. enableCountByExample="false" enableDeleteByExample="false"
    50. enableSelectByExample="false" enableUpdateByExample="false">
    51. table>
    52. context>
    53. generatorConfiguration>

    3.3 代码生成

    自动生成代码的目录列表如下:

     然后将每个实体类对象里面重写一下toString()方法即可。

    3.4 编写测试

    创建一个 名为 OrderItemVo 的类,继承OrderItem类,及属性有Order对象 

    1. package com.Kissship.vo;
    2. import com.Kissship.model.Order;
    3. import com.Kissship.model.OrderItem;
    4. /**
    5. * @author Kissship
    6. * @site www.Kissship.com
    7. * @company xxx公司
    8. * @create 2023-09-04-10:24
    9. */
    10. public class OrderItemVo extends OrderItem {
    11. private Order order;
    12. public Order getOrder() {
    13. return order;
    14. }
    15. public void setOrder(Order order) {
    16. this.order = order;
    17. }
    18. }

     在自动生成的OrderItemMapper.xml配置文件中进行增加以下配置:

    1. <resultMap id="OrderItemMap" type="com.Kissship.vo.OrderItemVo" >
    2. <result column="order_item_id" property="orderItemId" >result>
    3. <result column="product_id" property="productId" >result>
    4. <result column="quantity" property="quantity" >result>
    5. <result column="oid" property="oid" >result>
    6. <association property="order" javaType="com.Kissship.model.Order">
    7. <result column="order_id" property="orderId" >result>
    8. <result column="order_no" property="orderNo" >result>
    9. association>
    10. resultMap>
    11. <select id="selectByBiid" resultMap="OrderItemMap" parameterType="java.lang.Integer" >
    12. SELECT * FROM
    13. t_hibernate_order o ,
    14. t_hibernate_order_item oi
    15. WHERE o.order_id = oi.oid
    16. AND oi.order_item_id = #{oiid}
    17. select>

    在自动生成的 OrderItemMapper 接口中进行增加以下代码:

     OrderItemVo selectByBiid(@Param("oiid") Integer oiid);

    创建一个接口名为 : OrderItemBiz 接口

    1. package com.Kissship.biz;
    2. import com.Kissship.vo.OrderItemVo;
    3. /**
    4. * @author Kissship
    5. * @site www.Kissship.com
    6. * @company xxx公司
    7. * @create 2023-09-04-10:31
    8. */
    9. public interface OrderItemBiz {
    10. OrderItemVo selectByBiid(Integer oiid);
    11. }

     实现以上创建的接口,创建一个实现了名为 OrderItemBizImpl 

    1. package com.Kissship.biz;
    2. import com.Kissship.mapper.OrderItemMapper;
    3. import com.Kissship.vo.OrderItemVo;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.stereotype.Service;
    6. /**
    7. * @author Kissship
    8. * @site www.Kissship.com
    9. * @company xxx公司
    10. * @create 2023-09-04-10:42
    11. */
    12. @Service
    13. public class OrderItemBizImpl implements OrderItemBiz {
    14. @Autowired
    15. private OrderItemMapper orderItemMapper;
    16. @Override
    17. public OrderItemVo selectByBiid(Integer oiid) {
    18. return orderItemMapper.selectByBiid(oiid);
    19. }
    20. }

     创建一个测试类 名为 Test01 ,用来进行方法测试

    1. package com.Kissship.biz;
    2. import com.Kissship.vo.OrderItemVo;
    3. import org.junit.After;
    4. import org.junit.Before;
    5. import org.junit.Test;
    6. import org.junit.runner.RunWith;
    7. import org.springframework.beans.factory.annotation.Autowired;
    8. import org.springframework.test.context.ContextConfiguration;
    9. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    10. /**
    11. * @author Kissship
    12. * @site www.Kissship.com
    13. * @company xxx公司
    14. * @create 2023-09-04-10:42
    15. */
    16. @RunWith(SpringJUnit4ClassRunner.class)
    17. @ContextConfiguration(locations={"classpath:spring-context.xml"})
    18. public class Test01 {
    19. @Autowired
    20. private OrderItemBiz orderItemBiz;
    21. @Before
    22. public void setUp() throws Exception {
    23. }
    24. @After
    25. public void tearDown() throws Exception {
    26. }
    27. @Test
    28. public void selectByBiid() {
    29. OrderItemVo orderItemVo = orderItemBiz.selectByBiid(27);
    30. System.out.println(orderItemVo);
    31. System.out.println(orderItemVo.getOrder());
    32. }
    33. }

     执行测试类中selectByBiid()的方法,结果如图 : 

     四、一对多关联映射

    创建一个 名为 OrdeVo 的类,继承Order类,及属性有List集合

    用来存储查询到的OrderItem对象,因为是一对多所有查询出有多个对象,如下:

    1. package com.Kissship.vo;
    2. import com.Kissship.model.Order;
    3. import com.Kissship.model.OrderItem;
    4. import java.util.ArrayList;
    5. import java.util.List;
    6. /**
    7. * @author Kissship
    8. * @site www.Kissship.com
    9. * @company xxx公司
    10. * @create 2023-09-04-10:24
    11. */
    12. public class OrderVo extends Order {
    13. private List orderItems = new ArrayList<>();
    14. public List getOrderItems() {
    15. return orderItems;
    16. }
    17. public void setOrderItems(List orderItems) {
    18. this.orderItems = orderItems;
    19. }
    20. }

     在自动生成的 OrderMapper.xml 配置文件中增加以下配置,如下:

    1. <resultMap id="OrderVoMap" type="com.Kissship.vo.OrderVo">
    2. <result column="order_id" property="orderId" >result>
    3. <result column="order_no" property="orderNo" >result>
    4. <collection property="orderItems" ofType="com.Kissship.model.OrderItem">
    5. <result column="order_item_id" property="orderItemId" >result>
    6. <result column="product_id" property="productId" >result>
    7. <result column="quantity" property="quantity" >result>
    8. <result column="oid" property="oid" >result>
    9. collection>
    10. resultMap>
    11. <select id="selectByOid" resultMap="OrderVoMap" parameterType="java.lang.Integer" >
    12. SELECT * FROM
    13. t_hibernate_order o ,
    14. t_hibernate_order_item oi
    15. WHERE o.order_id = oi.oid
    16. AND o.order_id = #{oid}
    17. select>

     在自动生成的 OrderMapper接口中进行增加以下代码,如下:

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

     创建一个接口名为 : OrderBiz 接口

    1. package com.Kissship.biz;
    2. import com.Kissship.vo.OrderVo;
    3. /**
    4. * @author Kissship
    5. * @site www.Kissship.com
    6. * @company xxx公司
    7. * @create 2023-09-04-11:12
    8. */
    9. public interface OrderBiz {
    10. OrderVo selectByOid(Integer oid);
    11. }

    在实现以上 OrderBiz 接口,创建一个实现类,名为 OrderBizImpl 

    1. package com.Kissship.biz;
    2. import com.Kissship.mapper.OrderMapper;
    3. import com.Kissship.vo.OrderVo;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.stereotype.Service;
    6. /**
    7. * @author Kissship
    8. * @site www.Kissship.com
    9. * @company xxx公司
    10. * @create 2023-09-04-11:14
    11. */
    12. @Service
    13. public class OrderBizImpl implements OrderBiz {
    14. @Autowired
    15. private OrderMapper orderMapper;
    16. @Override
    17. public OrderVo selectByOid(Integer oid) {
    18. return orderMapper.selectByOid(oid);
    19. }
    20. }

     在测试类( Test01 )中增加以下测试方法及接口:

    1. @Autowired
    2. private OrderBiz orderBiz;
    3. @Test
    4. public void selectByOid() {
    5. OrderVo orderVo = orderBiz.selectByOid(7);
    6. System.out.println(orderVo);
    7. orderVo.getOrderItems().forEach(System.out::println);
    8. }

     执行其中的方法进行测试,结果为如图  :

    五、多对多关联映射

    在自动生成的 HBookMapper.xml 配置文件中增加以下配置:

    1. <resultMap id="CategoryVoMap" type="com.Kissship.vo.CategoryVo">
    2. <result column="category_id" property="categoryId">result>
    3. <result column="category_name" property="categoryName">result>
    4. <collection property="hbooks" ofType="com.Kissship.model.HBook">
    5. <result column="book_id" property="bookId">result>
    6. <result column="book_name" property="bookName">result>
    7. <result column="price" property="price">result>
    8. collection>
    9. resultMap>
    10. <select id="selectByCategoryId" resultMap="CategoryVoMap" parameterType="java.lang.Integer" >
    11. SELECT * FROM
    12. t_hibernate_book b,
    13. t_hibernate_book_category bc ,
    14. t_hibernate_category c
    15. WHERE b.book_id = bc.bid
    16. AND bc.cid = c.category_id
    17. AND c.category_id = #{cid}
    18. select>

     在自动生成的 HBookMapper 接口 中增加以下方法:

    HbookVo selectByBookId(@Param("bid") Integer bid);

     创建一个接口名为 HBookBiz 

    1. package com.Kissship.biz;
    2. import com.Kissship.vo.HbookVo;
    3. import org.apache.ibatis.annotations.Param;
    4. /**
    5. * @author Kissship
    6. * @site www.Kissship.com
    7. * @company xxx公司
    8. * @create 2023-09-04-11:25
    9. */
    10. public interface HBookBiz {
    11. HbookVo selecByBookId(@Param("bid") Integer bid);
    12. }

     然后再实现以上 HBookBiz 接口,创建一个实现类,名为 HBookBizImpl 

    1. package com.Kissship.biz;
    2. import com.Kissship.mapper.HBookMapper;
    3. import com.Kissship.vo.HbookVo;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.stereotype.Service;
    6. /**
    7. * @author Kissship
    8. * @site www.Kissship.com
    9. * @company xxx公司
    10. * @create 2023-09-04-11:26
    11. */
    12. @Service
    13. public class HBookBizImpl implements HBookBiz {
    14. @Autowired
    15. private HBookMapper hBookMapper;
    16. @Override
    17. public HbookVo selecByBookId(Integer bid) {
    18. return hBookMapper.selectByBookId(bid);
    19. }
    20. }

    在测试类( Test01 )中增加以下测试方法及接口:

    1. @Autowired
    2. private HBookBiz hbookBiz;
    3. @Test
    4. public void selectByBookId() {
    5. HbookVo hBookVo = hbookBiz.selecByBookId(8);
    6. System.out.println(hBookVo);
    7. hBookVo.getCategories().forEach(System.out::println);
    8. }

     执行其中的方法进行测试,结果为如图  :

    在自动生成的 CategoryMapper.xml 配置文件中增加以下配置:

    1. <resultMap id="CategoryVoMap" type="com.Kissship.vo.CategoryVo">
    2. <result column="category_id" property="categoryId">result>
    3. <result column="category_name" property="categoryName">result>
    4. <collection property="books" ofType="com.Kissship.model.HBook">
    5. <result column="book_id" property="bookId">result>
    6. <result column="book_name" property="bookName">result>
    7. <result column="price" property="price">result>
    8. collection>
    9. resultMap>
    10. <select id="selectByCategoryId" resultMap="CategoryVoMap" parameterType="java.lang.Integer" >
    11. SELECT * FROM
    12. t_hibernate_book b,
    13. t_hibernate_book_category bc ,
    14. t_hibernate_category c
    15. WHERE b.book_id = bc.bid
    16. AND bc.cid = c.category_id
    17. AND c.category_id = #{cid}
    18. select>

    在自动生成的 CategoryMapper 接口 中增加以下方法:

    CategoryVo selectByCategoryId(@Param("cid") Integer cid);

     创建一个接口名为 CategoryBiz 

    1. package com.Kissship.biz;
    2. import com.Kissship.vo.CategoryVo;
    3. /**
    4. * @author Kissship
    5. * @site www.Kissship.com
    6. * @company xxx公司
    7. * @create 2023-09-04-11:37
    8. */
    9. public interface CategoryBiz {
    10. CategoryVo selectByCategoryId(Integer cid);
    11. }

    然后再实现以上 CategoryBiz 接口,创建一个实现类,名为 CategoryBizImpl 

    1. package com.Kissship.biz;
    2. import com.Kissship.mapper.CategoryMapper;
    3. import com.Kissship.vo.CategoryVo;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.stereotype.Service;
    6. /**
    7. * @author Kissship
    8. * @site www.Kissship.com
    9. * @company xxx公司
    10. * @create 2023-09-04-11:38
    11. */
    12. @Service
    13. public class CategoryBizImpl implements CategoryBiz {
    14. @Autowired
    15. private CategoryMapper categoryMapper;
    16. @Override
    17. public CategoryVo selectByCategoryId(Integer cid) {
    18. return categoryMapper.selectByCategoryId(cid);
    19. }
    20. }

     在测试类( Test01 )中增加以下测试方法及接口 
     

    1. @Autowired
    2. private CategoryBiz categoryBiz;
    3. @Test
    4. public void selectByCategoryId() {
    5. CategoryVo categoryVo = categoryBiz.selectByCategoryId(8);
    6. System.out.println(categoryVo);
    7. categoryVo.getHbooks().forEach(System.out::println);
    8. }

    执行其中的方法进行测试,结果为如图  :

    六、小结 

    • 使用 元素配置结果集的映射关系,指定数据库列和 Java 对象属性之间的映射。
    • 可以使用 元素将数据库列映射到 Java 对象的属性,并指定属性的类型、映射关系及相关配置。
    • 可以使用 元素配置关联对象的映射关系,用于映射复杂对象之间的关系。
    • 可以使用 元素配置集合类型对象的映射关系,用于映射一对多或多对多的关系。
    • 使用 元素定义可重用的 SQL 片段,提供了组织和共享 SQL 语句的能力。 

    最后Mybatis关联关系映射与表对象之间的关系就到这里,祝大家在敲代码的路上一路通畅!

    感谢大家的观看 !

  • 相关阅读:
    微软10月补丁 | 修复103个漏洞,包括2个零日漏洞,13个严重漏洞
    互换性测量与技术——偏差与公差的计算,公差图的绘制,配合与公差等级的选择方法
    AD - 将修改后的 PCB 封装更新到当前 PCB 中
    dubbo(2):zookeeper和dubbo-admin的安装
    李宁「向上」:不止缺一个FILA
    【Vue2.0源码学习】生命周期篇-初始化阶段(initInjections)
    KMP算法 ← C++实现
    免费录音转文字的软件有哪些?不知道的小伙伴快来码住
    硬件玩物 | 性价比超高的NAS,威联通【TS-464-C2】快速上手初体验!
    第16章_瑞萨MCU零基础入门系列教程之CAN 协议
  • 原文地址:https://blog.csdn.net/weixin_74263417/article/details/132661444