Mybatis 的级联和延迟加载

Mybatis 的级联

使用 association 处理一对一关联关系

association: 映射到 JavaBean 的某个“复杂类型”属性,比如 JavaBean 类,即在 JavaBean 内部嵌套一个 复杂类型JavaBean属性。
association使用方法:
User.java

    package sqlmapper;
    public class User {
        private Integer id;
        private String username;
        private String password;
        private Integer age;
        private String telephone;
        private Integer userrole;
        private Role role;
        ...此处省略setter和getter方法
    }

Role.java

package sqlmapper;
public class Role {
    private Integer roleId;
    private String roleName;
    private String roleCode;
  ...此处省略setter和getter方法
}

比较简单且关联不多的场景

  • 在UserMapper.xml 中,由于 User 对象内部嵌套JavaBean 对象(Role),因此需要使用 association 类实现结果映射。
       <resultMap  id="userRoleResult" type="sqlmapper.User">
    		<id property="id" column="id" />
    		<result property="username" column="username" />
    		<association property="role" javaType="sqlmapper.Role" resultMap="BaseResultMap"/>
    	</resultMap>
       <resultMap id="BaseResultMap" type="sqlmapper.Role">
    		<id column="roleId"  property="roleId" />
    		<result column="roleName"  property="roleName" />
    		<result column="roleCode"  property="roleCode" />
    	</resultMap>  

也可以这样写:

    <resultMap  id="userRoleResult" type="sqlmapper.User">
    		<id property="id" column="id" />
    		<result property="username" column="username" />
    		<association property="role" javaType="sqlmapper.Role" >
    			<id column="roleId"  property="roleId" />
    			<result column="roleName"  property="roleName" />
    			<result column="roleCode"  property="roleCode" />
    		</association>
    </resultMap>

简单分析 association 的属性:

  • javaType:完整Java类名或者别名。
  • property:映射到数据路列的实体对象的属性,此处为在 User 里定义的属性:role

association 的子元素如下:

  • property:映射到数据库里的实体对象的属性。此处为Role的属性。
  • column:数据库列名

复杂且关联较多的场景

Role 对应的Mapper 文件:RoleMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="sqlmapper.RoleMapper">
	<select id="getRoleById" resultType="sqlmapper.Role" parameterType="int">
	select * from role where roleId=#{id}
	</select>
</mapper>

User 对应的Mapper 文件:UserMapper.xml

	<resultMap  id="userRoleResults" type="sqlmapper.User">
		<id property="id" column="id" />
		<result property="username" column="username" />
		<association property="role" column="userRole" select="sqlmapper.RoleMapper.getRoleById"/>
	</resultMap>
	<select id="getUserById" resultMap="userRoleResults"
		parameterType="int">
		select *
		from user
		where id=#{id}
	</select>
  • property:代表映射到 POJO 属性上。
  • select:select 配置是命名空间+SQL id 形式,这样便可以指向对应 Mapper 的 SQL,Mybatis 就会通过对应的 SQL 将数据查询回来。
  • column:代表SQL的列,用作参数传递给 select 属性制定的 SQL ,如果是多个参数,则需要用逗号隔开。

使用 collection 处理一对一关联关系

collection 元素的作用其实跟 association 差不多,只是 collection 只是映射到 JavaBean 的某个属性是一个类的列表。
如在User 类中增加个Address的列表属性:

 private List<Address> addressList;

则使用 collection 来映射。UserMapper.xml 关键代码如下:

    <resultMap  id="userRoleResult" type="sqlmapper.User">
    		<id property="id" column="id" />
    		<result property="username" column="username" />
    		<association property="addressList" ofType="sqlmapper.Address" >
    			<id column="id"  property="aid" />
    			<result column="postCode"  property="postCode" />
    			<result column="tel"  property="tel" />
    		</association>
    </resultMap>

跟 association 的用法差不多,就是 association 中的 javaType 改成 ofType 而已。

Mybatis 的加载延迟

Mybatis 支持延迟加载,我们希望一次性把常用的级联数据(针对association 和 collection)通过 SQL 直接查询出来,而对于那些不常用的级联数据不要取出,而是等待要用时才取出,这些不常用的级联数据可以采用延迟加载的功能。
在Mybatis 的 settings 配置中配置是否加载延迟:

    <setting >
    	<setting name="lazyLoadingEnabled" value="true">
    	<setting name="aggressiveLazyLoading" value="false">  #为false启动按需加载
    </setting >
  • 选项 lazyLoadingEnabled 决定是否开启延迟加载,
  • 而选项 aggressiveLazyLoading 为 true 的时候,一加载对象(任何一个属性)就会加载他的全部属性(如:调用User对象的任何一个属性的时候就为这个User对象加载它的 role 属性)。为 false 的时候,就是按需加载,调用User对象 的 role属性时才会去数据库查询并加载它的 role 属性的数据。

此外, Mybatis 中 还有 fetchType 属性。它存在两个值。

  • eager:获得当前POJO 后立即加载对应的数据。
  • lazy:获得当前POJO后延迟加载对应的数据。
    如:
	<resultMap  id="userRoleResults" type="sqlmapper.User">
		<id property="id" column="id" />
		<result property="username" column="username" />
		<association property="role" column="userRole"  fetchType="eager" select="sqlmapper.RoleMapper.getRoleById"/>
	</resultMap>

这样就会初始化对象的时候就为这个对象加载它的 role 属性。改成 fetchType=“lazy” 则调用User 的 role属性时才会加载它的 role 属性的数据。
fetchType 属性会忽略全局配置项 lazyLoadingEnabled 和 aggressiveLazyLoading 的配置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis级联查询可以通过在Mapper文件中使用嵌套查询的方式实现,具体步骤如下: 1. 在POJO类中定义关联属性(如一对多、多对多等),并提供对应的setter和getter方法。 2. 在Mapper文件中定义对应的嵌套查询语句,使用关联属性的getter方法来获取关联对象的数据,例如: ```xml <select id="findUserById" parameterType="int" resultMap="userResultMap"> select * from user where id = #{id} </select> <resultMap id="userResultMap" type="User"> <id column="id" property="id"/> <result column="username" property="username"/> <result column="age" property="age"/> <association property="department" javaType="Department"> <id column="dept_id" property="id"/> <result column="dept_name" property="name"/> </association> </resultMap> <select id="findUserWithDeptById" parameterType="int" resultMap="userResultMap"> select u.*, d.dept_name from user u left join department d on u.dept_id = d.id where u.id = #{id} </select> ``` 在上述代码中,`findUserById`只查询User表中的数据,而`findUserWithDeptById`则查询User表和Department表中的数据,并将Department作为User对象的关联属性返回。 3. 在业务层中调用Mapper接口的方法,即可进行级联查询,例如: ```java User user = userMapper.findUserWithDeptById(1); System.out.println(user.getDepartment().getName()); ``` 在上述代码中,`userMapper.findUserWithDeptById`方法会返回一个User对象,其中的Department属性已经被赋值为关联的Department对象,通过getDepartment()方法即可获取Department对象的数据。 需要注意的是,在进行级联查询时,需要定义好关联属性的类型和对应的嵌套查询语句,否则会导致查询失败或数据不完整。同时,级联查询也会增加数据库的查询开销,应该根据实际情况进行使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值