n+1问题:在默认情况下,使用query.iterator()查询,有可能有n+1问题,所谓n+1是指在查询对象的时候发出n+1条查询语句。
1:先发出查询id列表的sql语句。
N:再发出根据id到缓存中查询,如果缓存中有与之匹配的数据,就从缓存中取得数据,否则依次根据id发出sql语句。
list和iterator到区别:
list:在默认情况下,list每次都会发出sql查询实体对象,list会向缓存里放数据,但是不会利用缓存中的数据。
iterator:首先发出一条查询id列表的sql语句,如果缓存中有与之匹配的数据,就从缓存中取得数据,否则依次根据id发出sql语句。
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
import org.hibernate.Session;
import org.hibernate.Transaction;
//...
public class QueryTest extends TestCase {
public void testQuery1() {
Session session = null;
Transaction t = null;
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
/**
* 采用list查询,将发出一条sql语句来获取student数据
* Hibernate: select student0_.id as id1_, student0_.name as name1_ from Student student0_
张三
李四
*/
List<Student> list = session.createQuery("from Student").list();
for (Iterator<Student> iter = list.iterator(); iter.hasNext();) {
Student student = iter.next();
System.out.println(student.getName());
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}
public void testQuery2() {
Session session = null;
Transaction t = null;
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
/**
* N+1问题:
* 使用iterator,先发出查询id列表的sql语句,
* Hibernate: select student0_.id as col_0_0_ from Student student0_
* 再发出根据id查询实体对象的sql
* Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_ from Student student0_ where student0_.id=?
张三
Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_ from Student student0_ where student0_.id=?
李四
×
*/
Iterator<Student> it = session.createQuery("from Student").iterate();
while(it.hasNext()){
Student student = it.next();
System.out.println(student.getName());
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}
public void testQuery3() {
Session session = null;
Transaction t = null;
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
List<Student> list = session.createQuery("from Student").list();
for (Iterator<Student> iter = list.iterator(); iter.hasNext();) {
Student student = iter.next();
System.out.println(student.getName());
}
System.out.println("=======================");
/**
* 不会出现n+1问题
* 因为list操作已经将对象加入到一级缓存,所以在使用iterator的时候,
* 他首先发出查询id列表的sql,再根据id到缓存中获取数据,
* 只有在缓存中找不到,才再次发出sql语句
Hibernate: select student0_.id as id1_, student0_.name as name1_ from Student student0_
张三
李四
=======================
Hibernate: select student0_.id as col_0_0_ from Student student0_
张三
李四
*/
Iterator<Student> it = session.createQuery("from Student").iterate();
while(it.hasNext()){
Student student = it.next();
System.out.println(student.getName());
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}
}
分享到:
相关推荐
Hibernate 实体类 注解及功能说明。
hibernateOperate.java DeleteTest.java HibernateSessionFactory.java BatchUpdateTest.java
MyEclipse10.7由表自动生成Hibernate实体对象,由本人亲自实践,非常实用。。
6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法 6.4.1 increment标识符生成器 6.4.2 identity标识符生成器 6.4.3 sequence标识符生成器 6.4.4 hilo标识符生成器 ...
使用本地sql语句查询后,无需再使用Object对查询结果进行强制转换,而是直接将查询结果放到实体Bean里了。 PS: 其实只有一版,这里只所以叫最终版是因为该附件我上传了好几天传不上去,到最后报告说‘资源已经存在...
MyEclipse由表自动生成Hibernate实体对象_白杨,是一个非常好的ORcl,MYEXCLIpce 教材
Hibernate实体层设计.rar hibernate就是一个面向对象的一个框架
主要介绍了Hibernate实体对象继承的方法的相关资料,需要的朋友可以参考下
05_传智播客hibernate教程_实体对象的三种状态与saveOrUpdate方法
hibernate@注解方式配置实体类时,利用javadoc接口生成数据库表及字段的注释说明,支持oracle、sqlserver、db2、mysql数据库。因用到java\lib\tools.jar,需要将该jar放入工程lib下(或者tomcat\lib下、或加入...
hibernate概述,hibernate入门Demo,hibernate配置文件详解(全局配置,实体类映射配置),配置实体规则,核心API详解(Configuration,sessionFactory,session,Transaction),hibernate中的对象状态以及刷新能缓存机制 ...
介绍的很详细,个人觉得不错!!!
6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法 6.4.1 increment标识符生成器 6.4.2 identity标识符生成器 6.4.3 sequence标识符生成器 6.4.4 hilo标识符生成器 ...
6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法 6.4.1 increment标识符生成器 6.4.2 identity标识符生成器 6.4.3 sequence标识符生成器 6.4.4 hilo标识符生成器 ...
6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法 6.4.1 increment标识符生成器 6.4.2 identity标识符生成器 6.4.3 sequence标识符生成器 6.4.4 hilo标识符生成器 ...
6.3 Hibernate用对象标识符(OID)来区分对象 126 6.4 Hibernate的内置标识符生成器的用法 128 6.4.1 increment标识符生成器 131 6.4.2 identity标识符生成器 133 6.4.3 sequence标识符生成器 134 6.4.4 hilo...
(4)利用Hibernate的第三方工具或Eclipse的有关插件从数据库中创建出相应的实体对象及其ORM映射文件。 (5)创建Hibernate的SessionFactory类。 (6)通过SessionFactory创建Session实例。 (7)通过创建的...
Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性、关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性、...