1、什么是延迟加载

  延迟加载其实就是将数据加载时机推迟,比如推迟嵌套查询的执行时机(延迟加载也称懒加载,就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据)。在Mybatis中经常用到关联查询,但是并不是任何时候都需要立即返回关联查询结果。比如查询用户信息,并不一定需要及时返回用户下对应的账户信息,再比如查询商品分类信息并不一定要及时返回该类别下有哪些产品,这种情况一下需要一种机制,当需要查看时,再执行查询,返回需要的结果集,这种需求在Mybatis中可以使用延迟加载机制来实现。延迟加载可以实现先查询主表,按需实时做关联查询,返回关联表结果集,一定程度上提高了效率。

2、延迟加载的优缺点

  优点是:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能。缺点是:因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。

3、Mybatis怎么进行延迟加载

  1. 在mybatis主配置文件中开启延迟加载(lazyLoadingEnabled置为true),关闭攻击性延veLazyLoading置为false)
  2. 在映射配置文件中的association或collection标签中增加select属性

4、具体案例

4.1 pojo

4.1.1 User.java

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

4.1.2 Account.java

public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;
}

4.2 dao接口

4.2.1 UserMapper.java

public interface UserMapper {
    /**
     * 查询所有用户信息
     * @return
     */
    List<User> findAll();
}

4.2.2 AccountMapper.java

public interface AccountMapper {
    /**
     * 根据UID查询账户
     * @param uid
     * @return
     */
    List<Account> findByUid(@Param("uid") Integer uid);
}

4.3 配置文件

4.3.1 数据库配置文件

jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis
jdbc.username = root
jdbc.password = root

4.3.2 主配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="datasource.properties"></properties>
    
    <settings>
        <!-- 开启延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 关闭攻击性延迟加载 -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    
    <typeAliases>
        <package name="com.itcast.pojo"/>
    </typeAliases>
    
    <environments default="development">
        <environment id="development">
            <transactionManager type="jdbc"></transactionManager>
            <dataSource type="pooled">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <package name="com.itcast.dao"/>
    </mappers>
</configuration>

4.3.3 映射配置文件

4.3.3.1 AccountMapper.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="com.itcast.dao.AccountMapper">
    <select id="findByUid" parameterType="java.lang.Integer" resultType="account">
        SELECT *
        FROM account
        WHERE uid = #{uid}
    </select>
</mapper>
4.3.3.1 UserMapper.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="com.itcast.dao.UserMapper">
    <resultMap id="userMap" type="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
        <collection property="accounts" javaType="java.util.List" ofType="account" select="com.itcast.dao.AccountMapper.findByUid" column="id"></collection>
    </resultMap>

    <select id="findAll" resultMap="userMap">
        SELECT * FROM user
    </select>
</mapper>

4.3 junit测试

public class UserTest {

    private InputStream inputStream;
    private SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
    private SqlSessionFactory sqlSessionFactory;
    private SqlSession sqlSession;
    private UserMapper userMapper;

    @Before
    public void init() throws Exception{
        //1. 读取配置文件
        this.inputStream = Resources.getResourceAsStream("SqlMapperConfig.xml");
        //2. 获取SqlSessionFactoryBuilder
        this.sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //3. 获取SqlSessionFactory
        this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        //4. 获取SqlSession
        this.sqlSession = sqlSessionFactory.openSession();
        //5. 获取接口的代理对象
        this.userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @After
    public void destroy() throws Exception{
        //8. 提交事务
        sqlSession.commit();
        //9. 关闭资源
        sqlSession.close();
        inputStream.close();
    }

    /**
     * 查询所有
     */
    @Test
    public void testFindAll() throws Exception {
        List<User> userList = this.userMapper.findAll();
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

4.3 测试结果

image.png


短腿臭柯基
9 声望2 粉丝

下一篇 »
Mybatis缓存

引用和评论

0 条评论