Mybatis的延迟加载

Mybatis的延迟加载

 一、什么是延迟加载

延迟加载:  就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.好处:  先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。坏处:  因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。

二、实现需求

需求:  查询账户(Account)信息并且关联查询用户(User)信息。如果先查询账户(Account)信息即可满足要求,当我们需要查询用户(User)信息时再查询用户(User)信息。把对用户(User)信息的按需去查询就是延迟加载。  association、collection 具备延迟加载功能。

三、使用association实现延迟加载  

需求:

查询账户信息同时查询用户信息。

3.1 账户的持久层dao接口

package com.llb.dao;import com.llb.domain.Account;import java.util.List;/** * Ceate By llb on 2019/8/7

*/publicinterface AccountMapper {


    /**    * 查询账户所对应的的用户

    */    List findAccountAndUser();

}

3.2 账户的持久层映射文件

    

    

        

        

        

        

             

    

3.3 用户的持久层接口

package com.llb.dao;import com.llb.domain.User;import java.util.List;/** * 用户的持久层接口

* Ceate By llb on 2019/8/5

*/publicinterface UserMapper {


    /**    * 根据id查询所有用户

    * @return*/    User findById(Integer id);

    /**    * 查询出所有用户,包含账户信息

    * @return*/    List findAccountAndUser();

}

3.4 用户的持久层映射文件

   

       

           

               

               

               

               

               

               

                   

                       

                       

                   

                       

           

       


3.5 开启mybatis的延迟加载策略

进入 Mybaits 的官方文档,找到 settings 的说明信息:


Mybatis的延迟加载_第1张图片

我们需要在 Mybatis 的配置文件 SqlMapConfig.xml 文件中添加延迟加载的配置。

   

   

       

       

       

       

   

3.6 编写测试只查账户信息不查用户信息

*/publicclass AccountTest {

    InputStream in =null;

    AccountMapper mapper =null;

    SqlSession sqlSession =null;

    /**    * 在测试方法执行前执行

    * @throws IOException

    */    @Before

    publicvoidinit()throws IOException {

        //1.读取配置文件,生成字节流in = Resources.getResourceAsStream("SqlMapConfig.xml");

        //2.获取sqlSessionFactory对象SqlSessionFactory factory =new SqlSessionFactoryBuilder().build(in);

        //3.获取sqlSession对象sqlSession = factory.openSession();

        //4.获取dao的代理对象mapper = sqlSession.getMapper(AccountMapper.class);

    }

    /**    * 测试方法执行后执行

    * @throws IOException

    */    @After

    publicvoiddestory()throws IOException {

        sqlSession.commit();

        //6.释放资源        sqlSession.close();

        in.close();

    }

    /**    * 查询出账户所对应的user

    */    @Test

    publicvoid testFindAccountAndUser(){

        List accountUser = mapper.findAccountAndUser();//        for (Account account: accountUser) {//            System.out.println(account);//        }    }

}


3.7 测试结果

当不进行配置时,立即加载,查询account所对应的user,一起将user查询出来:

Mybatis的延迟加载_第2张图片

  配置后,对account进行查询放入到list集合中,并没有涉及到user对象,所以就没有发出 SQL 语句查询账户所关联的 User 对象的查询。:

四、使用collection实现缓存策略

同样我们也可以在一对多关系配置的结点中配置延迟加载策略。

结点中也有 select 属性,column 属性。

需求:

    完成加载用户对象时,查询该用户所拥有的账户信息。

4.1 在User实体类中加入List属性

package com.llb.domain;import java.io.Serializable;

import java.util.Date;import java.util.List;/** * Ceate By llb on 2019/8/5

*/publicclassUserimplements Serializable{

    private Integer id;

    private String username;

    private String address;

    private String sex;

    private Date birthday;

    //一对多关系。一的方包含多的一方所有对象privateList accounts;

    @Override

    public String toString() {

        return"User{" +                "id=" + id +                ", username='" + username + '\'' +                ", address='" + address + '\'' +                ", sex='" + sex + '\'' +                ", birthday=" + birthday +                ", accounts=" + accounts +                '}';

    }

    publicList getAccounts() {

        return accounts;

    }

    publicvoidsetAccounts(List accounts) {

        this.accounts = accounts;

    }

    public Integer getId() {

        return id;

    }

    publicvoid setId(Integer id) {

        this.id = id;

    }

    public String getUsername() {

        return username;

    }

    publicvoid setUsername(String username) {

        this.username = username;

    }

    public String getAddress() {

        return address;

    }

    publicvoid setAddress(String address) {

        this.address = address;

    }

    public String getSex() {

        return sex;

    }

    publicvoid setSex(String sex) {

        this.sex = sex;

    }

    public Date getBirthday() {

        return birthday;

    }

    publicvoid setBirthday(Date birthday) {

        this.birthday = birthday;

    }

}

4.2 编写用户接口和配置文件

UserMapper.class:

package com.llb.dao;import com.llb.domain.User;import java.util.List;/** * 用户的持久层接口

* Ceate By llb on 2019/8/5

*/publicinterface UserMapper {

    /**    * 根据id查询所有用户

    * @return*/    User findById(Integer id);

    /**    * 查询出所有用户,包含账户信息

    * @return*/    List findAccountAndUser();

}

UserMapper.xml:

    

    

    

    

    

    

    

4.3 使用测试方法进行测试

publicclass UserTest {

    InputStream in =null;

    UserMapper mapper =null;

    SqlSession sqlSession =null;

    /**    * 在测试方法执行前执行

    * @throws IOException

    */    @Before

    publicvoidinit()throws IOException {

        //1.读取配置文件,生成字节流in = Resources.getResourceAsStream("SqlMapConfig.xml");

        //2.获取sqlSessionFactory对象SqlSessionFactory factory =new SqlSessionFactoryBuilder().build(in);

        //3.获取sqlSession对象sqlSession = factory.openSession();

        //4.获取dao的代理对象mapper = sqlSession.getMapper(UserMapper.class);

    }

    /**    * 测试方法执行后执行

    * @throws IOException

    */    @After

    publicvoiddestory()throws IOException {

        sqlSession.commit();

        //6.释放资源        sqlSession.close();

        in.close();

    }

    /**    * 查询出所有用户所对应的账户

    */    @Test

    publicvoid findUserAndAccount(){

        List users = mapper.findAccountAndUser();

        }

}

测试结果:

  我们没有使用Accout,也只对User进行了查询。

Mybatis缓存

待更新。。。

源码:https://github.com/PopsiCola/SSM-mybatis/tree/association_lazy

欢迎star

你可能感兴趣的:(Mybatis的延迟加载)