n + 1问题
query.iterate()方式返回迭代查询会开始发出一条语句:查询所有记录ID语句
Hibernate: select student0_.id ascol_0_0_from t_student student0_
然后有多少条记录,会发出多少条查询语句。
n + 1问题:n:有n条记录,发出n条查询语句;1 :发出一条查询所有记录ID语句。
出现n+1的原因:因为iterate(迭代查询)是使用缓存的,第一次查询数据时发出查询语句加载数据并加入到缓存,以后再查询时hibernate会先到ession缓存(一级缓存)中查看数据是否存在,如果存在则直接取出使用,否则发出查询语句进行查询。
session=HibernateUtils.getSession(); tx = session.beginTransaction(); /** * 出现N+1问题 * 发出查询id列表的sql语句 * Hibernate: select student0_.idas col_0_0_ from t_student student0_ * * 再依次发出根据id查询Student对象的sql语句 * Hibernate: select student0_.idas id1_0_, student0_.name as name1_0_, * student0_.createTime ascreateTime1_0_, student0_.classesid as classesid1_0_ * from t_student student0_ wherestudent0_.id=? */ Iterator students =session.createQuery("fromStudent").iterate(); while (students.hasNext()){ Student student=(Student)students.next(); System.out.println(student.getName()); } tx.commit();先执行query.list(),再执行query.iterate,这样不会出现N+1问题
因为list操作已经将Student对象放到了一级缓存中,所以再次使用iterate操作的时候
它首先发出一条查询id列表的sql,再根据id到缓存中取数据,只有在缓存中找不到相应的
数据时,才会发出sql到数据库中查询
List students =session.createQuery("from Student").list(); for (Iterator iter =students.iterator();iter.hasNext();){ Student student=(Student)iter.next(); System.out.println(student.getName()); } System.out.println("---------------------------------------------------------"); // 不会出现N+1问题,因为list操作已经将数据加入到一级缓存。 Iterator iters=session.createQuery("from Student").iterate(); while (iters.hasNext()){ Student student=(Student)iters.next(); System.out.println(student.getName()); }list 和 iterate不同之处
a) list取所有
b) Iterate先取ID,等用到的时候再根据ID来取对象
c) session中list第二次发出,仍会到数据库查询
d) iterate第二次,首先找session级缓存
Session级缓存(一级缓存)
一级缓存很短和session的生命周期一致,因此也叫session级缓存或事务级缓存
哪些方法支持一级缓存:
get()
load()
iterate(查询实体对象)
如何管理一级缓存:
session.clear(),session.evict()
如何避免一次性大量的实体数据入库导致内存溢出
先flush,再clear
如果数据量特别大,考虑采用jdbc实现,如果jdbc也不能满足要求可以考虑采用数据本身的特定导入工具
相关文章
- 07-23数据分析之解析电影中如下问题
- 07-23hibernate学习三 精解Hibernate之核心文件
- 07-23Qt5配置OpenCV之问题总结
- 07-23海思AI芯片(HI35xx):tensorflow转caffemodel之环境和权限问题
- 07-23海思AI芯片(HI35xx):tensorflow转caffemodel之numpy版本问题
- 07-23struts神马的不过是对servlet、filter的封装而已,hibernate神马的也不过是对jdbc的封装而已,他们只是把一些常见的操作流程化了,如果不懂servlet、filter,不懂jdbc,使用struts和hibernate出问题了都不知道是怎么回事。
- 07-23面试知识点总结之开放性问题
- 07-23iOS之深入探究多线程实现、线程死锁和线程安全问题
- 07-23drools简单实例之报关费问题
- 07-23Algorithm:数学建模大赛之数学建模基础(经验/技巧)、流程(模型准备/模型假设/建模/求解/分析/优化/预测/评价)、论文写作(意义/摘要/关键词/问题重述和模型假设/建模/文献)之详细攻略