当前位置:   article > 正文

Mybatis关联关系映射与表对象之间的关系_mybatis如何设置查询字段与bean对象的映射关系

mybatis如何设置查询字段与bean对象的映射关系

目录

一、关联关系映射

1.1 一对一

1.2 一对多

 1.3 多对多

二、处理关联关系的方式

2.1 嵌套查询

2.2 嵌套结果

三、一对一关联映射

3.1 建表

​编辑 3.2 配置文件

3.3 代码生成

3.4 编写测试

 四、一对多关联映射

五、多对多关联映射

六、小结 


一、关联关系映射

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

1.1 一对一

一对一关联映射:

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

1.2 一对多

一对多关联映射:

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

 1.3 多对多

多对多关联映射:

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

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

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

二、处理关联关系的方式

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

2.1 嵌套查询

嵌套查询(Nested Selects):

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

2.2 嵌套结果

嵌套结果(Nested Results):

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

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

无论使用哪种方式,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. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE 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. <!-- 引入配置文件 -->
  6. <properties resource="jdbc.properties"/>
  7. <!--指定数据库jdbc驱动jar包的位置-->
  8. <classPathEntry location="D:\\temp2\\mvn_repository\\mysql\\mysql-connector-java\\5.1.44\\mysql-connector-java-5.1.44.jar"/>
  9. <!-- 一个数据库一个context -->
  10. <context id="infoGuardian">
  11. <!-- 注释 -->
  12. <commentGenerator>
  13. <property name="suppressAllComments" value="true"/><!-- 是否取消注释 -->
  14. <property name="suppressDate" value="true"/> <!-- 是否生成注释代时间戳 -->
  15. </commentGenerator>
  16. <!-- jdbc连接 -->
  17. <jdbcConnection driverClass="${jdbc.driver}"
  18. connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/>
  19. <!-- 类型转换 -->
  20. <javaTypeResolver>
  21. <!-- 是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.) -->
  22. <property name="forceBigDecimals" value="false"/>
  23. </javaTypeResolver>
  24. <!-- 01 指定javaBean生成的位置 -->
  25. <!-- targetPackage:指定生成的model生成所在的包名 -->
  26. <!-- targetProject:指定在该项目下所在的路径 -->
  27. <javaModelGenerator targetPackage="com.Kissship.model"
  28. targetProject="src/main/java">
  29. <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
  30. <property name="enableSubPackages" value="false"/>
  31. <!-- 是否对model添加构造函数 -->
  32. <property name="constructorBased" value="true"/>
  33. <!-- 是否针对string类型的字段在set的时候进行trim调用 -->
  34. <property name="trimStrings" value="false"/>
  35. <!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 -->
  36. <property name="immutable" value="false"/>
  37. </javaModelGenerator>
  38. <!-- 02 指定sql映射文件生成的位置 -->
  39. <sqlMapGenerator targetPackage="com.Kissship.mapper"
  40. targetProject="src/main/java">
  41. <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
  42. <property name="enableSubPackages" value="false"/>
  43. </sqlMapGenerator>
  44. <!-- 03 生成XxxMapper接口 -->
  45. <!-- type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象 -->
  46. <!-- type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象 -->
  47. <!-- type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 -->
  48. <javaClientGenerator targetPackage="com.Kissship.mapper"
  49. targetProject="src/main/java" type="XMLMAPPER">
  50. <!-- 是否在当前路径下新加一层schema,false路径com.oop.eksp.user.model, true:com.oop.eksp.user.model.[schemaName] -->
  51. <property name="enableSubPackages" value="false"/>
  52. </javaClientGenerator>
  53. <!-- 配置表信息 -->
  54. <!-- schema即为数据库名 -->
  55. <!-- tableName为对应的数据库表 -->
  56. <!-- domainObjectName是要生成的实体类 -->
  57. <!-- enable*ByExample是否生成 example类 -->
  58. <!--<table schema="" tableName="t_book" domainObjectName="Book"-->
  59. <!--enableCountByExample="false" enableDeleteByExample="false"-->
  60. <!--enableSelectByExample="false" enableUpdateByExample="false">-->
  61. <!--&lt;!&ndash; 忽略列,不生成bean 字段 &ndash;&gt;-->
  62. <!--&lt;!&ndash; <ignoreColumn column="FRED" /> &ndash;&gt;-->
  63. <!--&lt;!&ndash; 指定列的java数据类型 &ndash;&gt;-->
  64. <!--&lt;!&ndash; <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> &ndash;&gt;-->
  65. <!--</table>-->
  66. <table schema="" tableName="t_hibernate_book" domainObjectName="HBook"
  67. enableCountByExample="false" enableDeleteByExample="false"
  68. enableSelectByExample="false" enableUpdateByExample="false">
  69. </table>
  70. <table schema="" tableName="t_hibernate_category" domainObjectName="Category"
  71. enableCountByExample="false" enableDeleteByExample="false"
  72. enableSelectByExample="false" enableUpdateByExample="false">
  73. </table>
  74. <table schema="" tableName="t_hibernate_book_category" domainObjectName="HBookCategory"
  75. enableCountByExample="false" enableDeleteByExample="false"
  76. enableSelectByExample="false" enableUpdateByExample="false">
  77. </table>
  78. <table schema="" tableName="t_hibernate_order" domainObjectName="Order"
  79. enableCountByExample="false" enableDeleteByExample="false"
  80. enableSelectByExample="false" enableUpdateByExample="false">
  81. </table>
  82. <table schema="" tableName="t_hibernate_order_item" domainObjectName="OrderItem"
  83. enableCountByExample="false" enableDeleteByExample="false"
  84. enableSelectByExample="false" enableUpdateByExample="false">
  85. </table>
  86. </context>
  87. </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>集合

用来存储查询到的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<OrderItem> orderItems = new ArrayList<>();
  14. public List<OrderItem> getOrderItems() {
  15. return orderItems;
  16. }
  17. public void setOrderItems(List<OrderItem> 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. }

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

六、小结 

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

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

感谢大家的观看 !

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/625673
推荐阅读
相关标签
  

闽ICP备14008679号