关于Mybatis的延迟加载之一对一&&一对多查询

延迟加载的定义

就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载

优点

先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

缺点

因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。

首先我们需要在主配值文件中加上这一段话

<settings>
    <!--开启延迟加载-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!--关闭即时加载 在mybatis3.4.1以后 默认就是关闭的-->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

一对一延迟加载

首先我们要有两张表
一张user表
一张account表
在这里插入图片描述

因为是一对一查询 那么显然一个账户对应一个用户

因此我们在配置文件中加上以下内容

<resultMap id="AccountUserMapper" type="com.tubai.domain.Account">
    <id property="ID" column="id"></id>
    <result property="UID" column="uid"></result>
    <result property="money" column="money"></result>
    <!--根据查询出来的uid作为参数传递给select中的方法-->
    <association property="user" column="uid" javaType="com.tubai.domain.User"
    select="com.tubai.dao.UserDao.findUserByID">
    </association>
</resultMap>
<select id="selectAll" resultMap="AccountUserMapper">
    select * from account;
</select>

这是Accout类的属性

private Integer ID;
private Integer UID;
private Double money;
//与用户建立一对一的联系
private User user;

这是User类的属性

private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//这个是一对多查询的部分使用到的 这里暂时忽略
private List<Account> accountList;
思考

可以发现我们的采用延迟加载的话,我们的sql语句是非常简洁的,仅仅是单纯的查询所有而已,并不存在其他的外连接什么的复杂sql。

那么我们是如何完成延迟查询的呢?
我们发现我们的association标签中有一个属性select

select="com.tubai.dao.UserDao.findUserByID"

这个属性调用了一个方法,这个方法是通过用户id来查询用户的

那么参数从哪来?我们发现属性中还有一个叫

column="uid"

破案了,Mybatis就是在需要用到用户信息的时候 ,才会去调用我们提供的方法。这样就成功实现了懒加载

测试

我们写一个测试方法

@Test
public void testSelectAll() throws Exception{
    List<Account> accounts = accountDao.selectAll();
    for (Account account : accounts) {
        System.out.println(account);
        System.out.println(account.getUser());
    }
}

执行,我们从控制台中发现和立即加载没有任何区别
在这里插入图片描述

是因为我们这里使用到了account

如果我们将使用到account的部分注释掉

变成以下形式

@Test
public void testSelectAll() throws Exception{
    List<Account> accounts = accountDao.selectAll();
    for (Account account : accounts) {
        //System.out.println(account);
        //System.out.println(account.getUser());
    }
}

再一次执行 我们发现延迟加载的效果就出现了
在这里插入图片描述并没有去查询关于user的部分(因为我们没有使用到,也就不需要去访问了)

一对多延迟加载

一个用户可以拥有多个账户 那么我们仿照上面的思路

我们可以写下这样的配置文件

<resultMap id="userAccountMap" type="com.tubai.domain.User">
    <id property="id" column="id"></id>
    <result property="username" column="username"></result>
    <result property="sex" column="sex"></result>
    <result property="address" column="address"></result>
    <result property="birthday" column="birthday"></result>
    <!--使用集合存储则需要用collection-->
    <!--ofType是指集合中的每个元素是什么-->
    <collection property="accountList" ofType="com.tubai.domain.Account"
    select="com.tubai.dao.AccountDao.findAccountByUid" column="id">
    </collection>
</resultMap>
<select id="selectAll" resultMap="userAccountMap">
    select * from user
</select>

同样的和一对一查询进行测试

@Test
public void testSelectAll()throws Exception{
    List<User> users = userDao.selectAll();
    //一对多延迟加载 当访问到user的时候 才会动态的调用查询语句 来给accountList赋值
    for (User user : users) {
        System.out.println("每个用户的信息");
        System.out.println(user);
        System.out.println(user.getAccountList());
    }
}

在这里插入图片描述

@Test
public void testSelectAll()throws Exception{
    List<User> users = userDao.selectAll();
    //一对多延迟加载 当访问到user的时候 才会动态的调用查询语句 来给accountList赋值
    for (User user : users) {
        /*System.out.println("每个用户的信息");
        System.out.println(user);
        System.out.println(user.getAccountList());*/
    }
}

在这里插入图片描述

通过以上测试 我们就能简易的明白延迟加载及其使用了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值