Loading

mybatis延迟加载

参考:你真的懂了mybatis延迟加载吗?

什么是mybatis延迟加载

这玩意就是为了替代多表联合查询的,将一次多表查询换成多次查询,这样再暂时不需要一些数据的时候就可以节省资源

举个例子:

有两张表:

  • 图书表(book):
  • 图书类型表(category):

    我们可以这样做在类型实体类里面添加一个属性存放该类型下的图书
public class Category {
    private int cid;
    private String cname;
    private List<Book> books;
	//省略get set
}

想要查询数据的话
则要使用这样一个sql语句

SELECT book.*,cname FROM book,category WHERE book.cid = category.cid

假设我们是先显示类别,再展开类别,对于每个类别再去显示相应的书籍的时候
我们就会发现如果没有展开一些项目的时候,查询到的数据就浪费了
所以我们就会采用两个sql语句去先查出所有的类别,再根据需要对某个类别查出对应的书籍

我们可以手动的写两个Select语句去实现 或者 利用mybatis延迟加载的功能

mybatis延迟加载相对于直接用两个sql的好处

可以把两个SQL,假装成一个联合查找的sql来用,减少了java的代码量
在需要的时候会自动调用相应的sql,更加方便

延迟加载的配置

mapper.xml的配置

<mapper namespace="cn.xh.dao.UserDao">
    <select id="findCategoryWithLazingload" resultMap="categoryMap">
        select * from category
    </select>
    <resultMap id="categoryMap" type="cn.xh.pojo.Category">
        <id column="cid" property="cid"></id>
        <result column="cname" property="cname"></result>

        <collection property="books" column="cid" select="findBookWithLazy"></collection>
    </resultMap>

    <select id="findBookWithLazy" parameterType="int" resultType="cn.xh.pojo.Book">
        select * from book where cid = #{cid}
    </select>
</mapper>

<collection property="books" column="cid" select="findBookWithLazy"></collection>
collection,association是支持延迟加载的,

  • select属性表示要执行的sql语句
  • column表示执行sql语句要传的参数,该参数为select * from category查询出来的字段cid,
  • property=”books”表示查询出来的结果给到books属性

在这里插入图片描述

在mybatis的核心配置文件中配置:

<settings>
    <!-- 开启延迟加载-->
    <setting name="lazyLoadingEnabled" value="true" />
    <!-- 关闭立即加载-->
    <setting name="aggressiveLazyLoading" value="false" />
    <!-- 设定tostring等方法延迟加载-->
    <setting name="lazyLoadTriggerMethods" value="true" />
</settings>

运行效果

@Test
public void testDo(){
    SqlSession session = sqlSessionFactory.openSession();
    UserDao u =  session.getMapper(UserDao.class);//用动态代理的方式自动生成接口的实现类
 	List<Category> lst  =  u.findCategoryWithLazingload();
 	for (Category c : lst) {
        System.out.println(c.getCname());
 
    }
    session.close();
}

在这里插入图片描述
这里执行了sql语句:Select * from category

@Test
public void testDo1(){
    SqlSession session = sqlSessionFactory.openSession();
    UserDao u =  session.getMapper(UserDao.class);//用动态代理的方式自动生成接口的实现类
 	List<Category> lst  =  u.findCategoryWithLazingload();
 	for (Category c : lst) {
        System.out.println(c.getCname());
    }
    List<Book> lstBook = lst.get(0).getBooks();
    session.close();
}

在这里插入图片描述
这里执行了sql语句:Select * from book where cid = ?

对比这两段代码,可以看到, 只有当执行List<Book> lstBook = lst.get(0).getBooks();这行代码的时候才会去执行sql语句Select * from book where cid = ?

这就是延迟加载里的按需执行sql语句,只有在需要的时候才会去执行。

总结:延迟加载就是按需加载,在需要查询的时候再去查询,使用延迟加载可以避免表连接查询表连接查询比单表查询的效率低但是它需要多次与数据库进行交互,所以延迟加载并不是万能的,使用需谨慎。

posted @ 2021-03-30 09:50  克豪  阅读(54)  评论(0)    收藏  举报