当前位置: 首页 > news >正文

Mybatis的延迟加载

1.什么是延迟加载

当加载用户信息时,不一定就要马上加载他的订单信息或者所有的好友信息,聊天记录等等,这样就需要用到延迟加载。

当我们需要用到数据的时候才进行加载,不用数据的时候就不加载,也可以叫做懒加载。

优点

先从单表查询,需要时再从关联表去关联查询,⼤⼤提⾼数据库性能,因为查询单表要比关联查询多张表速度要快。

缺点

因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成⽤户等待时间变长,造成用户体验下降。

在多表中:
一对多,多对多:通常情况下采用延迟加载
一对一(多对一):通常情况下采用立即加载

注意:
延迟加载是基于(嵌套查询)来实现的

2.实现

局部延迟加载

associationcollection标签中都有⼀个fetchType属性,通过修改它的值,可以修改局部的加载策略。

<?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.lazyload.mapper.IAccountMapper"> <!--将Account的信息和User的信息封装到ResultMap中去--> <!-- property表示java实体类中属性的名称,javaType表示属性的类型,ofType表示泛型,column表示应用查询的某列 select表示需要执行的sql语句 fetchType表示是否开启延迟加载eager取消延迟加载,lazy开启延迟加载,默认开启 --> <resultMap id="userAccountMap" type="com.lazyload.entites.Account"> <id property="id" column="id"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <!--一对一的映射关系:配置封装的内容 select属性指定的内容:查询用户的唯一标识【com.itheima.dao.IAccountMapper+方法名(就是接口中的)】 column属性指定的内容:根据id查询时,所需要的参数的值(根据id来查询数据库的) --> <association property="user" column="uid" javaType="com.lazyload.entites.User" select="findAccountByUid" feetchType="lazy"></association> </resultMap> <!--封装的查询所有--> <select id="findAllAccount" resultMap="userAccountMap"> select * from account </select> <!--根据用户id查询账户列表--> <select id="findAccountByUid" parameterType="integer" resultType="com.lazyload.entites.Account"> select * from account where uid=#{uid} </select> </mapper>
<?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.lazyload.mapper.IUserMapper"> <!--写入user的resultMap:将user和数据库对应 作用:建立SQL查询结果字段与实体属性的映射关系 --> <resultMap id="userAccountMap" type="com.lazyload.entites.User"> <!--主键字段--> <!--column所表示的是数据库中的字段名称--> <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> <!--Userx下对应的对应Account账户的信息:配置user对象下account的映射--> <collection property="accounts" select="findUserById" column="id"></collection> </resultMap> <!--查询所有--> <select id="findAll" resultMap="userAccountMap"> select * from user </select> <!--查询一个通过id--> <select id="findUserById" parameterType="int" resultType="com.lazyload.entites.User"> select * from user where id=#{id} </select> </mapper> 参考链接:https://blog.csdn.net/friggly/article/details/124686876?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_utm_term~default-0-124686876-blog-108432460.235^v38^pc_relevant_default_base&spm=1001.2101.3001.4242.1&utm_relevant_index=3

当查询用户基本信息时,只返回用户基本信息,而不进行其余账号信息的查询,当触发关键方法的时候才进行查询,具体的进入参考链接学习讲的非常好,到位学习链接。

全局延迟加载

#全局启用延迟加载 mybatis.configuration.lazy-loading-enable=true #为false时,所有关联对象都会按需求加载 mybatis.configuration.aggressive-lazy-loading=false #设置方法触发加载,不设置时默认为下面这几个方法触发 mybatis.configuration.lazy-load-trigger-methods=equals,clone,hashCode

局部加载策略优先级高于全局加载策略,同时在xml映射文件里修改feetchType属性为eager来取消延迟加载。

3、延迟加载原理实现


它的原理是,使用 CGLIB 或 Javassist( 默认 ) 创建目标对象的代理对象。当调用代理对象的延迟加载属性的 getting 方法时,进入拦截器方法。比如调⽤ a.getB().getName() 方法,进入拦截器的invoke(...) 方法,发现 a.getB() 需要延迟加载时,那么就会单独发送事先保存好的查询关联 B对象的 SQL ,把 B 查询上来,然后调用a.setB(b) 方法,于是 a 对象 b 属性就有值了,接着完成a.getB().getName() 方法的调用。这就是延迟加载的基本原理。

总结:延迟加载主要是通过动态代理的形式实现,通过代理拦截到指定方法,执行数据加载。

http://www.jsqmd.com/news/446885/

相关文章:

  • 教程 | 如何动用智慧安装NavicatPremium 16
  • Python 潮流周刊#141:Python 早期贡献者口述历史
  • Web前端之旋转木马的图片效果、鼠标进入停止动画、keyframes、hover、child、nth
  • canvas_3_绘制弧形
  • linux-centos常用指令、tar.gz解压、mv重命名、cp复制、ss -ltnp、curl测试任意端口网络是否可达等
  • 女生必看!用OpenClaw龙虾当你的24小时免费助理,职场、生活效率翻倍,做自己的女王!
  • 2026年宜昌两天一夜游路线权威榜单:十大精品路线深度评测与排位赛 - 品牌推荐
  • 软考知识总结
  • python pip 更新
  • MySQL为什么有了redolog还需要double write buffer?
  • 实习面经摘录回答(四)
  • CPU中央处理器(下)
  • 2026年留学生求职必看:中国留学生求职机构选型指南与适配场景全解析 - 品牌推荐
  • vue+elementui完美模拟pc版快手实现短视频,含短视频详情播放
  • TeXLive2023 pdflatex编译eps图像,出现错误的问题
  • 2026年用户口碑最佳的中国留学生求职机构推荐:五家真实服务体验与成果对比 - 品牌推荐
  • android scrollview嵌套webview,滚动冲突解决
  • 2026年中国留学生求职机构深度测评:基于海内外资源覆盖的五维战力解析 - 品牌推荐
  • 第二:Jmeter - 环境搭建
  • 2026年北京审计事务所深度测评:基于上市公司服务与跨境业务能力的五维对比 - 品牌推荐
  • 2026年游客口碑最好的宜昌两天一夜游路线推荐:五大真实体验与避坑对比 - 品牌推荐
  • xLua实现背包的热更新实践
  • Web前端之微信小程实现上下左右全向滑动切换、复杂解构、bindtouchstart、bindtouchend、parseInt
  • 第一:Jmeter-JDK安装和环境变量配置
  • 2026年隐私安全充电宝品牌深度测评:五维安全技术全解析与实战对比 - 品牌推荐
  • 前端「页面懒加载」
  • 软件工程:职业全景与前景深度解析 - 教程
  • 2026年短途度假必看:宜昌两天一夜游路线选型指南与场景化适配攻略 - 品牌推荐
  • 互联网大厂Java面试剧情:内容社区场景下Spring Boot/微服务/AI技术全解
  • Web前端之vue+element-puls的el-form-item实现label和内容换行、同时具有多个类名才起作用的条件样式写法、css类名条件判断、多条件选择器、样式选择器、initial