MyBatis 的高级映射和延迟加载是优化数据库操作的重要特性,下面为你详细介绍:
一、高级映射
高级映射用于处理复杂的对象关系(如一对一、一对多、多对多),主要通过resultMap实现。
1. 一对一映射
通过association标签实现,适用于实体间的has-one关系。
示例:用户(User)和账户(Account)的一对一关系
<resultMap id="userResultMap"type="User"><id property="id"column="id"/><result property="username"column="username"/><association property="account"javaType="Account"><id property="id"column="account_id"/><result property="balance"column="balance"/></association></resultMap>2. 一对多映射
通过collection标签实现,适用于实体间的has-many关系。
示例:订单(Order)和订单项(OrderItem)的一对多关系
<resultMap id="orderResultMap"type="Order"><id property="id"column="id"/><result property="orderNo"column="order_no"/><collection property="items"ofType="OrderItem"><id property="id"column="item_id"/><result property="productName"column="product_name"/></collection></resultMap>3. 多对多映射
通过中间表关联,通常使用collection配合子查询或连接查询实现。
示例:用户(User)和角色(Role)的多对多关系
<resultMap id="userRoleResultMap"type="User"><id property="id"column="id"/><result property="username"column="username"/><collection property="roles"ofType="Role"><id property="id"column="role_id"/><result property="roleName"column="role_name"/></collection></resultMap>二、延迟加载(Lazy Loading)
延迟加载允许在需要时才加载关联对象,避免一次性加载所有数据,提高性能。
1. 开启延迟加载
在mybatis-config.xml中配置:
<settings><settingname="lazyLoadingEnabled"value="true"/><settingname="aggressiveLazyLoading"value="false"/><!-- 按需加载 --></settings>2. 实现方式
嵌套查询(子查询):通过
select属性指定子查询。<resultMap id="userResultMap"type="User"><id property="id"column="id"/><result property="username"column="username"/><association property="account"column="id"select="selectAccountByUserId"fetchType="lazy"/><!--显式指定延迟加载--></resultMap><select id="selectAccountByUserId"parameterType="int"resultType="Account">SELECT*FROMaccountWHEREuser_id=#{id}</select>嵌套结果(连接查询):通过
fetchType="lazy"指定延迟加载。<resultMap id="userResultMap"type="User"><id property="id"column="id"/><result property="username"column="username"/><association property="account"javaType="Account"fetchType="lazy"><id property="id"column="account_id"/><result property="balance"column="balance"/></association></resultMap>
三、高级映射与延迟加载的配合
通过resultMap和fetchType结合,可灵活处理复杂关系的加载时机。
示例:按需加载用户的订单和订单详情
<resultMap id="userWithOrders"type="User"><id property="id"column="id"/><collection property="orders"column="id"select="selectOrdersByUserId"fetchType="lazy"/></resultMap>四、注意事项
- N+1 查询问题:延迟加载可能导致多次查询(主查询 + N 个子查询),可通过
<batch>模式或二级缓存优化。 - 会话生命周期:延迟加载需确保调用时 SqlSession 未关闭(可使用
OpenSessionInView模式)。 - 性能权衡:避免过度延迟加载,对频繁访问的关联数据建议立即加载。
五、总结
- 高级映射:通过
resultMap处理复杂关系,支持嵌套查询和嵌套结果。 - 延迟加载:按需加载关联对象,提升性能,但需注意 N+1 问题。
合理使用这两个特性,可显著优化 MyBatis 的查询效率和代码可维护性。