MyBatis的延迟加载

1.什么是延迟加载?

      当我们在使用MyBatis进行数据库查询时,通常会使用一种称为“立即加载”的方式。 这意味着当查询主对象时,MyBatis会立即加载该对象及其关联对象的所有数据。 但是,有时关联对象的数据可能会很大,而且并不一定每次都需要完整加载所有的关联对象数据。 这就是延迟加载的作用。 延迟加载是一种性能优化技术,它允许在需要的时候才去加载关联对象的数据,而不是在查询主对象时就一次性加载所有关联对象。 这样可以避免不必要的数据库查询,提高查询性能和减轻数据库负载。

     开启延迟加载后,在真正使用数据的时候才发起级联查询,不用的时候不查询。

1.1.局部配置延迟加载

在xxx.xml文件<resultMap><collection></collection> </resultMap>标签中配置

property="accounts":属性名
ofType="com.by.pojo.Account":集合的泛型,等价于resultType
select="com.by.mapper.AccountMapper.selectAccountByUid":要调用的select标签的id
column="id":传递给select查询的参数
fetchType="lazy":延迟加载,默认没有开启延迟加载

1.2.全局配置延迟加载

在mybatis-config.xml文件中<configuration></configuration>标签配置
    <settings>
       <!--开启懒加载(开启延迟加载)-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--   false 深入式延迟加载   true 侵入式延迟加载 -->
         <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

 2.案例代码

2.1.pojo

public class User {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    private List<Account> accounts;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public List<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                ", accounts=" + accounts +
                '}';
    }
}

2.2.Mapper

public interface UserMapper {
   User getUserById(Integer id);
}
<?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">
<!--namespace:隔离sql,一般是接口名称的全类名-->
<mapper namespace="com.zh.mapper.UserMapper">
    <resultMap id="getUserByIdResultMap" type="user">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="sex" property="sex"></result>
        <result column="birthday" property="birthday"></result>
        <result column="address" property="address"></result>
        <!--延迟加载的一对多-->
        <!--
            property="accounts":属性名
            ofType="com.by.pojo.Account":集合的泛型,等价于resultType
            select="com.by.mapper.AccountMapper.selectAccountByUid":要调用的select标签的id
            column="id":传递给select查询的参数
            fetchType="lazy":延迟加载,默认没有开启延迟加载
        -->
        <collection property="accounts"
                    ofType="com.zh.pojo.Account"
                    select="com.zh.mapper.AccountMapper.selectAccountByUid"
                    column="id">
        </collection>
    </resultMap>
    <select id="getUserById" resultMap="getUserByIdResultMap">
            select * from user where id=#{id}
    </select>
</mapper>

2.3.测试

public class MyBatisTest {
    private SqlSession session;
    private InputStream inputStream;
    @Before
    public void before() throws Exception{
        //加载配置文件
        String resource = "mybatis-config.xml";
         inputStream = Resources.getResourceAsStream(resource);
        //创建一个sqlSessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获得数据库的会话实例
         session = sessionFactory.openSession();
    }   

 /**
     * 延迟加载:一对多
     * */
    @Test
    public void testGetUserById() throws Exception{
        //返回接口的代理类
        UserMapper userMapper = session.getMapper(UserMapper.class);
        User user = userMapper.getUserById(41);
        System.out.println(user.getUsername());
        List<Account> accounts = user.getAccounts();
       accounts.forEach(account -> System.out.println(account));
    }

    @After
    public void close() throws Exception{
        //关闭资源
        inputStream.close();
        session.close();
    }
}

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值