博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate综合问题
阅读量:6673 次
发布时间:2019-06-25

本文共 2201 字,大约阅读时间需要 7 分钟。

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我们不能满足数据的要求本身就可以被认为是一个特定的导入工具

版权声明:本文博主原创文章,博客,未经同意不得转载。

你可能感兴趣的文章
css去掉a标签点击后的虚线框
查看>>
机器学习:逻辑回归
查看>>
Java字符编码的转化问题
查看>>
Node.js 连接 MySQL
查看>>
02-线性结构3. 求前缀表达式的值(25)
查看>>
csdn知识库
查看>>
安卓实训第四天--基于HttpClient来完毕数据在server和设备间的交互。
查看>>
软件測试、ios中的測试概念以及步骤
查看>>
具体图解 Flume介绍、安装配置
查看>>
tensorflow 1.0 学习:池化层(pooling)和全连接层(dense)
查看>>
LeetCode96_Unique Binary Search Trees(求1到n这些节点能够组成多少种不同的二叉查找树) Java题解...
查看>>
JAVA常见算法题(十二)
查看>>
spring-boot-oracle spring-batch
查看>>
URL编码与解码
查看>>
面向对象设计原则一:单一职责原则(SRP)
查看>>
Codeforces 839D Winter is here【数学:容斥原理】
查看>>
在js中怎样获得checkbox里选中的多个值?
查看>>
基于AllegroGraph实现Protege设计知识库模型的存储步骤
查看>>
线程中释放锁的方式
查看>>
VM环境下Linux虚拟机扩展存储空间操作方法总结
查看>>