广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Mybatis如何实现关联属性懒加载
  • 408
分享到

Mybatis如何实现关联属性懒加载

2024-04-02 19:04:59 408人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

mybatis 关联属性懒加载 延迟加载配置 mybatis默认没有开启延迟加载,需要在config.xml中setting配置。 lazyLoadingEnabled:true使用

mybatis 关联属性懒加载

延迟加载配置

mybatis默认没有开启延迟加载,需要在config.xml中setting配置。

lazyLoadingEnabled:true使用延迟加载,false禁用延迟加载,默认为false。

aggressiveLazyLoading:true启用时,当延迟加载开启时访问对象中一个懒对象属性时,将完全加载这个对象的所有懒对象属性。false,当延迟加载时,按需加载对象属性(即访问对象中一个对象属性时,不会加载对象中的引用属性)。默认为true。

修改延迟加载需要的select语句

延迟加载场景分析

查询订单时,需要关联查询订单明细表

假设有10 个订单,每个订单有5个明细信息。

如果用户仅仅需要查看订单信息,不需要订单明细信息,但是查询了10+50个对象到内存(只有10个是用户想要的)。显然是增加内存的负担。

如果用户的需求仅仅是查询订单信息,我仅仅订单信息用户,没有查询订单的详情,那么,内存中只有10对象(10个对象全是客户想的),这样做显然 节省了内存。

业务需求特点:需要的时候在进行查询,不需要的时候不尽兴查询,这种情况就是延迟加载,也叫作懒加载。

配置过程

去掉sql语句中对user表的查询语句

对resultMap orderAndUser 进行修改

注意:查询订单时要同时查询userid,避免查询user时没有凭据

修改orderMapper.xml文件select语句


<!-- 关联属性延迟加载 -->
	<select id="queryOrderAndUser" resultMap="orderAndUser">
		select
		o.id oids,o.orderid,o.createtime,o.note,o.userid
		from orders o,t_user u
		where o.userid=u.id
	</select>
	<resultMap type="orders" id="orderAndUser">
		<id property="id" column="oids"></id>
		<result property="orderId" column="orderid"></result>
		<result property="createtime" column="createtime" />
		<result property="note" column="note" />
		<association property="user" javaType="users" 
		select="net.neuedu.mybatis.mapper.UserMapper.queryUserById" column="userid">
			<!-- 
				这里不查询用户的信息,而是将用的信息放在另外一个查询中
				column是order表中的userid字段
			 -->
		</association>
	</resultMap>

因为在assocication多了一个select元素,就要在UserMapper中多加一个方法。


 //根据ID查询用户
 public Users queryUserById(Integer id);

在UserMapper.xml中添加queryUserById的select


 <!-- public Users queryUserById(Integer id); -->
 <select id="queryUserById" parameterType="int" resultType="users">
  select * from t_user where id=#{id}
 </select>

Mybatis注解方式懒加载失效分析

本人在使用spring mvc + mybatis的后台结构的项目的时候,在使用mybatis的懒加载出现了一些问题:

明明懒加载的配置都正确了,但就是用debug断点调试的时候懒加载的属性总是提前加载,在经过几天的不断努力之后,终于发现了原因:

mybatis懒加载配置:


<!-- 查询时,关闭关联对象即时加载以提高性能 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
<setting name="aggressiveLazyLoading" value="false" />

懒加载查询语句:


@Select("select * from user_main where username=#{username}")
 @Results({
       @Result(property = "roleNames", column = "id", many = @Many(fetchType=FetchType.LAZY,select = "getRoleNamesByUserId")),
       @Result(property = "permissionNames", column = "id", many = @Many(fetchType=FetchType.LAZY,select = "getPermissionsByUserId"))
   })
public UserPO getUserByUsername(@Param("username")String username);

测试用例:


 @Test
   public void testGetUserByUsername() throws Exception {
     SqlSession session = sqlSessionFactory.openSession();
     try {
       UserMapper userMapper = session.getMapper(UserMapper.class);
       UserPO userPo = userMapper.getUserByUsername("zhangsan");
       System.out.println(userPo);
       System.out.println(userPo.getPermissionNames());
//       List<String> map = userMapper.getRoleMain();
//       System.out.println(map);
       session.close();
     } finally {
       session.close();
     }
   }

结果调试测试用例的时候,使用debug却发现懒加载并没有生效,后来看了mybatis懒加载的源码,依然没有发现原因,感觉就是roleNames和permissionNames就是突然的加载了,断点也捕捉不到,也没有博捉到触发的事件,这时楼主我就很奇怪了,最后经过几天的努力终于发现了原因:

mybatis源码:configuration


protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(Arrays.asList(new String[] { "equals", "clone", "hashCode", "toString" }));

默认这四个方法或触发懒加载,当然,触发懒加载的方法还有getRoleNames 和 getPermissions ,这两个(只针对当前实例)

然后通过sysout输出的时候,发现hashcode和equals方法被莫名的触发了,而且debug断点还捕捉不到,然后roleNames和permissionNames就被莫名的加载了

最后发现,这个问题和debug的原理有一定的关系,

原来,在显示debug的黄色框框时,debug会另起一个线程,然后重新调用一遍代码,然后显示userpo信息的时候,又会调用userpo的hashcode方法和tostring方法,

这样的话,就会导致这两个方法会在debug线程内触发懒加载,造成的效果就是懒加载失效,但是实际上懒加载是生效了的,只是在debug模式上被触发了,而且用断点还捕捉不到,就会形成一个奇怪的问题,如果想用debug来查看效果,也是很简单:

通过将触发默认的四个方法屏蔽来查看效果,但是不支持,因为这样的话,可能会影响实体的hash排序等问题,即使是用了这个方法,也是建议看完效果以后改成默认的

这种事代码方式的,还有一种是配置文件方式的(自己从网上找)


configuration.setLazyLoadTriggerMethods(new HashSet<String>());

还有一种更好的方式来查看懒加载的效果,那就是mybatis的默认日志,建议将日志级别调成debug(这个debug级别和debug模式不一样),然后执行的时候就可以通过sql语句的打印来判断懒加载是否生效。

其实这个问题的分析最后,还是在说debug断点调试的问题,它的这种原理需要注意,特别是会在另一个线程调用hashcode和tostring方法,相信在很多方面会影响到我们,希望大家能够注意吧~

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Mybatis如何实现关联属性懒加载

本文链接: https://www.lsjlt.com/news/130437.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mybatis如何实现关联属性懒加载
    Mybatis 关联属性懒加载 延迟加载配置 mybatis默认没有开启延迟加载,需要在config.xml中setting配置。 lazyLoadingEnabled:true使用...
    99+
    2022-11-12
  • MyBatis懒加载如何实现
    这篇文章主要介绍“MyBatis懒加载如何实现”,在日常操作中,相信很多人在MyBatis懒加载如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MyBatis懒加载如何实现”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-30
  • mybatis中如何实现executor包懒加载功能 
    这篇文章主要为大家展示了“mybatis中如何实现executor包懒加载功能 ”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“mybatis中如何实现executor包懒加载功能&nb...
    99+
    2023-06-29
  • webpack如何实现懒加载和预加载
    小编给大家分享一下webpack如何实现懒加载和预加载,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!正常加载为了看的方便,index.js中的代码非常简单console.log('index.js执行了')...
    99+
    2023-06-22
  • android fragment懒加载如何实现
    Android Fragment的懒加载可以通过以下步骤实现:1. 在Fragment类中添加一个boolean类型的变量isLoa...
    99+
    2023-08-26
    android fragment
  • 如何通过IntersectionObserver实现懒加载
    通常懒加载等都会通过监听scroll事件用getBoundingClientRect()来判断元素位置来决定是否可以开始加载。性能开销是比较大的,为了节省性能又需要各种操作去弥补,例...
    99+
    2023-05-16
    IntersectionObserver懒加载
  • vue2组件如何实现懒加载
    这篇文章给大家分享的是有关vue2组件如何实现懒加载的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、 什么是懒加载懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。二、为什...
    99+
    2022-10-19
  • vue如何实现路由懒加载
    在vue中实现路由懒加载的方法有:1.使用import方法实现;2.使用require.ensure()方法实现;3.使用vue异步组件实现;具体方法如下:使用import方法实现路由懒加载const Home = () => import...
    99+
    2022-10-20
  • JavaScript如何实现图片懒加载
    这篇文章主要介绍了JavaScript如何实现图片懒加载,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。图片懒加载imagegetBoundClientRect 的实现方式,监...
    99+
    2023-06-27
  • vue-router如何实现路由懒加载
    这篇文章主要为大家展示了“vue-router如何实现路由懒加载”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue-router如何实现路由懒加载”这篇文章吧...
    99+
    2022-10-19
  • 如何实现前端图片懒加载
    这篇文章主要介绍了如何实现前端图片懒加载,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。定义图片懒加载又称图片延时加载、惰性加载,即在用户需要...
    99+
    2022-10-19
  • javascript如何实现图片预加载和懒加载功能
    这篇文章主要介绍“javascript如何实现图片预加载和懒加载功能”,在日常操作中,相信很多人在javascript如何实现图片预加载和懒加载功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”javascr...
    99+
    2023-06-14
  • js前端如何实现图片懒加载
    这篇文章主要介绍js前端如何实现图片懒加载,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!思路:将页面里所有img属性src属性用data-xx代替,当页面滚动直至此图片出现在可视区域...
    99+
    2022-10-19
  • 详解如何在Java中实现懒加载
    目录Java 中如何实现懒加载使用 Supplier 接口实现懒加载使用双重检查锁定模式实现懒加载Java 中如何实现懒加载 懒加载是一种常见的优化技术,它可以延迟对象的创建或初始化...
    99+
    2023-03-19
    Java实现懒加载 Java懒加载
  • 小程序列表懒加载如何实现
    本文小编为大家详细介绍“小程序列表懒加载如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“小程序列表懒加载如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。小程序上的列表懒加载长列表我们经常接触到,长列...
    99+
    2023-06-29
  • mybatis如何实现一对一关联映射
    小编给大家分享一下mybatis如何实现一对一关联映射,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言在客观世界中,对象很少是孤独存在的,如班级与学生之间的关系...
    99+
    2023-05-30
    mybatis
  • RecyclerChart动态属性图标联动数据动态加载怎么实现
    本篇内容介绍了“RecyclerChart动态属性图标联动数据动态加载怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!图表联动类似于股...
    99+
    2023-07-05
  • webpack如何实现缓存优化、合并、懒加载
    这篇文章主要介绍webpack如何实现缓存优化、合并、懒加载,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!除了的webpack基本配置,还可以进一步添加配置,优化合并文件,加快编译速...
    99+
    2022-10-19
  • jquery插件如何实现懒汉式加载图片
    这篇文章主要为大家展示了“jquery插件如何实现懒汉式加载图片”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“jquery插件如何实现懒汉式加载图片”这篇文章吧...
    99+
    2022-10-19
  • 小程序如何实现图片懒加载方式
    这篇文章主要介绍了小程序如何实现图片懒加载方式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。意义懒加载或者可以说是延迟加载,针对非首屏或者用...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作