经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MyBatis » 查看文章
Mybatis一对多查询列表属性处理示例详解
来源:jb51  时间:2023/5/15 9:00:28  对本文有异议

一、说明

1.<collection>标签属性说明

  • property:指定主对象中的集合属性名称。
  • ofType:指定集合元素的类型。默认值为java.lang.Object。可以通过指定 ofType 属性来指定集合元素的类型。
  • column:指定集合元素所用的列名,用于匹配结果集中的列。(内层select关联字段,若不指定则默认使用外键对应的主键作为column属性的值)
  • columnPrefix: 指定集合元素所用的列名前缀,用于匹配结果集中的列。(用于平铺查询方式下内层列映射自动匹配)
  • select:指定获取集合元素的 SQL 查询语句。
  • resultSetType:指定 SQL 查询结果集的类型,默认值为FORWARD_ONLY,还可以设置为SCROLL_SENSITIVE和SCROLL_INSENSITIVE,具体的用法可以参考JDBC文档。
  • fetchType:指定集合的加载方式,默认值为“lazy”,可选值为“eager”,当 fetchType 属性设置为“eager”时,MyBatis会在执行 SQL 语句返回结果集后,立即加载集合元素。
  • javaType: 指定集合的 Java 类型,通常不需要指定,MyBatis会根据集合属性的类型自动推断。
  • jdbcType: 指定集合属性在数据库中的类型,可以参考 JDBC 中的类型定义。如果不指定,MyBatis会自动推断。
  • notNullColumn:指定一个或多个属性列的名称,这些列不能为空。当这些属性列为空时,MyBatis会抛出异常。notNullColumn 属性可以使用逗号(,)分隔,以指定多个属性列。
  • columnOverride:指定一个或多个元素属性与结果集中列的映射关系。
  • typeHandler:指定一个元素属性的类型处理器。
  • ofTypeHandler:指定集合元素的类型处理器。
  • resultMap:指定集合元素的映射器,通常是通过嵌套 result 标签来定义,并使用该 resultMap 的 id 来指定。
  • orderBy:指定升序或降序。多个排序条件时,用空格分开。例如orderBy="id desc,create_time asc"表示先按id降序,再按createTime升序排列。(不推荐使用,建议在SQL中手动指定排序方式)
  • notNullColumn:指定一个或多个属性列的名称,这些列不能为空。当这些属性列为空时,MyBatis会抛出异常。notNullColumn 属性可以使用逗号(,)分隔,以指定多个属性列。
  • statementType:指定操作执行的SQL类型,有STATEMENT,PREPARED和CALLABLE三种,分别代表简单语句、预处理语句和调用存储过程。默认值为PREPARED。

columnPrefix用法

如果使用了 columnPrefix 属性,可以省略 result 标签中的 column 属性,并且 MyBatis 会自动完成属性与列名之间的映射。

  1. <resultMap id="userResultMap" type="User">
  2. <id column="user_id" property="id"/>
  3. <result column="user_name" property="name"/>
  4. <collection property="roles" ofType="Role">
  5. <id column="role_id" property="id"/>
  6. <result column="role_name" property="name"/>
  7. </collection>
  8. </resultMap>

改用columnPrefix前缀写法简化代码,使用使用时,多使用表别名作为列前缀,例如columnPrefix="r."

  1. <resultMap id="userResultMap" type="User">
  2. <id column="user_id" property="id"/>
  3. <result column="user_name" property="name"/>
  4. <collection property="roles" ofType="Role" columnPrefix="role_">
  5. <id column="role_id" property="id"/>
  6. <result property="name"/>
  7. </collection>
  8. </resultMap>

mybatis 官方文档

2. 示例代码

实体类

  1. public class User {
  2. private Integer id;
  3. private String name;
  4. private Integer age;
  5. private List<Order> orders;
  6.  
  7. // 省略 getter 和 setter 方法
  8. }
  9.  
  10. public class Order {
  11. private Integer id;
  12. private String orderNo;
  13. private Date createTime;
  14.  
  15. // 省略 getter 和 setter 方法
  16. }

二、平铺查询

可结合columnPrefixresultMap使用

Mybatis XML

  1. <select id="getUserOrdersById" resultMap="userResultMap">
  2. SELECT u.id, u.name, u.age, o.id AS order_id, o.order_no, o.create_time
  3. FROM user u
  4. INNER JOIN `order` o ON u.id = o.user_id
  5. WHERE u.id = #{id}
  6. </select>
  7. <resultMap id="userResultMap" type="com.example.User">
  8. <id property="id" column="id" />
  9. <result property="name" column="name" />
  10. <result property="age" column="age" />
  11. <collection property="orders" ofType="com.example.Order" resultMap="orderResultMap" />
  12. </resultMap>
  13. <resultMap id="orderResultMap" type="com.example.Order">
  14. <id property="id" column="order_id" />
  15. <result property="orderNo" column="order_no" />
  16. <result property="createTime" column="create_time" />
  17. </resultMap>

三、 嵌套查询(Nested Select for Collection)

嵌套查询支持惰性加载,可通过设置fetchType调整集合加载方式,默认值为“lazy”,可选值为“eager”。

3.1 外键查询

  1. <select id="getUserOrdersById" resultMap="userResultMap">
  2. SELECT u.id, u.name, u.age
  3. FROM user u
  4. WHERE u.id = #{id}
  5. </select>
  6. <select id="getOrderByUserId" resultMap="orderResultMap">
  7. SELECT o.id, o.order_no, o.create_time
  8. FROM `order` o
  9. WHERE o.user_id = #{userId}
  10. </select>
  11. <resultMap id="orderResultMap" type="com.example.Order">
  12. <id property="id" column="order_id" />
  13. <result property="orderNo" column="order_no" />
  14. <result property="createTime" column="create_time" />
  15. </resultMap>
  16. <resultMap id="userResultMap" type="com.example.User">
  17. <id property="id" column="id" />
  18. <result property="name" column="name" />
  19. <result property="age" column="age" />
  20. <collection property="orders" ofType="com.example.Order" resultMap="orderResultMap" select="getOrderByUserId" column="id">
  21. <!-- 这里使用 column="id",指定了内层 select 语句的参数值为外层查询语句结果集中的 id 属性值(即用户ID) -->
  22. </collection>
  23. </resultMap>

3.2 select传入多个参数

上面讲到指定select嵌套sql时,需要指定column="id",如果内层SQL需要传入多个参数时,可采用如下方式

  1. public class OrderQuery {
  2. private Long userId; // 用户id
  3. private Integer status; // 订单状态
  4. // getter和setter方法
  5. }
  1. <select id="getOrdersByUserId" resultType="Order">
  2. SELECT *
  3. FROM `order`
  4. WHERE user_id = #{userId}
  5. AND status = #{status}
  6. </select>
  7. <resultMap id="userMap" type="User">
  8. <id property="id" column="id"/>
  9. <result property="name" column="name"/>
  10. <result property="age" column="age"/>
  11. <!-- 注意这里的association标签的select属性使用了OrderQuery对象的属性 -->
  12. <result property="orders" column="id"
  13. select="com.example.mapper.OrderMapper.getOrdersByUserId">
  14. <association property="param" javaType="OrderQuery">
  15. <result property="userId" column="id"/>
  16. <result property="status" value="1"/> <!-- 这里传递的是固定值,也可以替换为动态的表达式 -->
  17. </association>
  18. </result>
  19. </resultMap>

association一对一属性处理

上面介绍一对多查询列表属性处理,其实association更常用于一对一属性的处理上

  1. package com.example;
  2.  
  3. public class Order {
  4. private int orderId;
  5. private String orderName;
  6. private Customer customer;
  7.  
  8. // getters and setters for orderId, orderName, customer
  9. }
  10.  
  11. package com.example;
  12.  
  13. public class Customer {
  14. private int customerId;
  15. private String customerName;
  16.  
  17. // getters and setters for customerId, customerName
  18. }
  1. <resultMap id="orderMap" type="com.example.Order">
  2. <id property="orderId" column="order_id"/>
  3. <result property="orderName" column="order_name"/>
  4. <association property="customer" javaType="com.example.Customer">
  5. <id property="customerId" column="customer_id"/>
  6. <result property="customerName" column="customer_name"/>
  7. </association>
  8. </resultMap>

在这个例子中,Order类有一个Customer属性,我们使用Association关联对象将query出的Customer映射到Order对象的Customer属性上。
需要注意的是,Association也可以嵌套使用,我们可以通过多层Association实现多个对象之间的关联。此外,需要注意的是,在映射关联对象Association时要确保SQL语句中的JOIN操作正确无误。

总结

到此这篇关于Mybatis一对多查询列表属性处理的文章就介绍到这了,更多相关Mybatis一对多查询列表属性内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号