栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Java从零到架构师第③季】【08】MyBatis-延迟加载

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Java从零到架构师第③季】【08】MyBatis-延迟加载


持续学习&持续更新中…

守破离


【Java从零到架构师第③季】【08】MyBatis-延迟加载
    • 为什么要使用延迟加载
    • 立即加载与延迟加载
        • 立即加载
        • 延迟加载
    • MyBatis的延迟加载
    • 实现延迟加载—需求一
    • 实现延迟加载—需求二
    • 全局延迟加载开关
    • 注意和一些建议
    • 参考

为什么要使用延迟加载

延迟加载:用到时 再加载

  • 很多时候,我们是暂时用不上某个对象的所有属性的,特别是那些复杂庞大的属性
  • 比如说,我现在只想知道Person对象的id和name,暂时使用不到Person对象的List、List
  • 而使用之前的查询方法会将Person的所有信息都查出来,会造成极大的浪费
  • 很多时候我们希望是在要用到某个对象的属性时(一般是集合collection类型的属性)才去加载它,而不是急着一次性的把它的所有信息都给搞出来
  • 也就是说,先将简单的属性加载出来,那些复杂庞大的在要使用到它们的时候再去加载它们。
  • 这时候就需要使用延迟加载技术了
立即加载与延迟加载 立即加载
  1. 一条SQL语句
  2. 可能会造成资源的浪费
  3. 如果不是集合类型、常用、比较小,可以考虑立即加载
延迟加载
  1. 多条SQL语句
  2. 这些SQL语句在不同的时机执行(被调用时执行。例:当person.getBankCards()时再去加载这个person对象的BankCard相关数据)
  3. 不会造成资源的浪费
  4. 如果是集合类型、不常用、比较大,建议延迟加载。
MyBatis的延迟加载

实现延迟加载—需求一
  • 需求:通过Person的id查询出对应的Person对象,对这个Person对象的idCard、bankCards、jobs三个成员变量实现延迟加载

  • 分析

    1. 既然要对Person对象的idCard、bankCards、jobs三个属性进行延迟加载 ,那么之前的SQL语句就需要修改,不能像之前那样一次性直接查询出所有内容
    2. 初始化查询时只需要查询出Person的id、name即可
    3. 当在Java中调用person.getIdCard()时,加载对应person对象的idCard;
    4. 当在Java中调用person.getBankCards()时,加载对应person对象的bankCards;
    5. 当在Java中调用person.getJobs()时,加载对应person对象的jobs;
    6. 这三个需要延迟加载的成员变量都需要通过对应person的id去单独的查询
    7. 那么这三个肯定要有属于自己的SQL查询语句
  • id_card.xml映射文件:

	
	    
	        SELECT id, no, address FROM id_card WHERe person_id = #{personId}
	    
	
  • bank_card.xml映射文件:
	
	    
	        SELECT id, name, duty
	        FROM job
	        JOIN person_job
	        ON 
	        	person_job.job_id = id AND person_job.person_id = #{personId}
	    
	
  • person.xml映射文件:
	
	
	
	    
	        SELECT id, name FROM person
	    
	    
	        
	        
	        
	        
	        
	    
	    
	
实现延迟加载—需求二
  • 需求:通过Person的id查询出对应的Person对象,只对这个Person对象的bankCards、jobs两个成员变量实现延迟加载

  • 分析

    1. 既然只对Person对象的bankCards、jobs这两个属性进行延迟加载
    2. 也就意味着初始化查询时需要查询出Person的id、name、idCard这三个属性
    3. 当在Java中调用person.getBankCards()时,加载对应person对象的bankCards;
    4. 当在Java中调用person.getJobs()时,加载对应person对象的jobs;
    5. 这两个需要延迟加载的成员变量都需要通过对应person的id去单独的查询
    6. 那么这两个肯定要有属于自己的SQL查询语句
  • bank_card.xml:

	
	    
	        SELECT id, name, duty
	        FROM job
	        JOIN person_job
	        ON 
	        	person_job.job_id = id AND person_job.person_id = #{personId}
	    
	
  • person.xml:
	
	    
	        SELECT person.id       person_id,
	               person.name     person_name,
	               id_card.id      id_card_id,
	               id_card.no      id_card_no,
	               id_card.address id_card_address
	        FROM person
	        JOIN id_card ON id_card.person_id = person.id
	    
	    
	        
	        
	        
	            
	            
	            
	        
	        
	        
	    
	    
	
全局延迟加载开关

  • lazyLoadingEnabled默认为false

  • 当某个关联对象配置了select属性时,是否延迟加载是可控制的:

    • fetchType="lazy"时,延迟加载
    • fetchType="eager"时,立即加载
    	
    
  • aggressiveLazyLoading是配合lazyLoadingEnabled(延迟加载)使用的。

  • aggressiveLazyLoading:激进的延迟加载,默认值为false

    • 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。
    • 不开启时,每个延迟加载属性会按需加载。
注意和一些建议
  • 使用IDEA的调试工具调试时、使用System.out直接打印MyBatis查询过来的对象时,看不出延迟加载效果
  • 因此想要看出延迟加载效果只能使用System.out打印查询出来的对象的某个属性

  • 如果在setting中配置了lazyLoadingEnabled为true的话,那么所有设置了select属性的关联对象都会默认开启延迟加载,就不用再写fetchType="lazy"属性了
  • 如果想要某个设置了select属性的关联对象采取立即加载的方式加载数据,那么需要使用fetchType="eager"来覆盖掉默认的懒加载行为

  • 如果不希望延迟加载,那么就像上面举例的那样,在查询“Person”的时候,就将其查询出来
  • 如果希望延迟加载,那么就不要在查询“Person”的时候将其查出,而是再搞一个SQl语句(select标签),让其当要用到的时候再去查询。
参考

小码哥-李明杰: Java从0到架构师③进阶互联网架构师.


本文完,感谢您的关注支持!


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/694008.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号