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操纵实体对象”中,我们将探讨如何使用Hibernate来创建、更新、删除和查询数据库中的实体对象。 首先,`HibernateSessionFactory`是Hibernate的核心组件之一,它负责创建`Session`对象。`...
**Hibernate实体对象操纵** 在Java开发中,Hibernate是一款非常重要的对象关系映射(ORM)框架,它极大地简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据库数据。本篇文章将深入探讨Hibernate中的...
2. **对象关系映射(ORM)**:详述Hibernate的实体类、注解和XML映射文件,如何定义对象的属性与数据库字段的对应关系,以及如何处理一对多、一对一、多对多等复杂关系。 3. **Session和Transaction管理**:讲解...
5. 自动反向生成实体对象:在MyEclipse中,可以使用Database Explorer功能实现从数据库表到Hibernate实体对象的自动反向工程。这个过程允许开发者快速生成实体类文件,从而减少手动编码的工作量。 6. 步骤说明: a...
如果查询返回的是单个对象,我们可以使用`addEntity()`方法指定结果应映射到的实体类: ```java query.addEntity(MyEntity.class); MyEntity result = (MyEntity) query.uniqueResult(); ``` 如果查询返回的是多个...
在Hibernate中,实体类代表数据库表,实体类的实例对应表中的记录,属性对应字段,这样就将复杂的SQL操作转化为简单的对象操作。 其次,书中详细讲解了Hibernate的配置。这包括了Hibernate的XML配置文件(hibernate...
本话题主要围绕如何根据数据库中的表生成Hibernate实体类进行展开。 首先,我们需要理解Hibernate实体类的作用。实体类是与数据库表对应的Java类,它们包含了表的字段和相关属性,以及由Hibernate提供的getter和...
- **双向关联**(标准关联):两个实体对象之间相互引用,如同远房亲戚互相认识。在Java代码中,这通常通过在两个类中设置相互的引用属性来实现,如`Wo`和`MeiNv`的例子。 - **单向关联**:仅有一方对象持有另一方...
《Hibernate实体层设计详解》 Hibernate,作为Java领域中的一款著名持久化框架,它将对象关系映射(ORM)的概念引入到数据库操作中,极大地简化了数据库编程工作。本篇文章将深入探讨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. **实体生命周期管理**:Hibernate自动管理对象的状态,包括瞬态、持久化、托管和脱管四种状态,以及它们之间的转换。 7. **多对一、一对多、多对多关系映射**:Hibernate支持复杂的关联关系映射,如单向关联、...
本资源“Hibernate实体映射”提供了一个深入理解这一关键概念的机会,通过实例代码和教程笔记,帮助学习者更好地掌握Hibernate的核心功能。 一、Hibernate实体映射基础 在Hibernate中,实体映射是将Java对象模型与...
总结,Hibernate操纵持久化对象涉及多个方面,包括对象状态管理、事务处理、查询机制、缓存策略以及关系映射等。熟练掌握这些概念和操作,将极大地提高开发效率,并有助于构建高效、稳定的数据库应用程序。通过实践...
使用本地sql语句查询后,无需再使用Object对查询结果进行强制转换,而是直接将查询结果放到实体Bean里了。 PS: 其实只有一版,这里只所以叫最终版是因为该附件我上传了好几天传不上去,到最后报告说‘资源已经存在...
**hibernate实体生成工具**是开发者在使用Hibernate框架时常用的一种辅助工具,它能够自动生成与数据库表对应的Java实体类,大大节省了手动编写代码的时间,提高了开发效率。Hibernate是一个强大的对象关系映射(ORM...
本教程将详细解释如何使用Hibernate将本地SQL查询的结果封装成对象,以便更好地理解和应用这项技术。 1. Hibernate ORM简介: Hibernate是一个开源的ORM框架,它为Java应用程序提供了数据持久化的解决方案。它通过...
在使用Hibernate进行查询前,首先需要进行基本的配置,包括创建hibernate.cfg.xml配置文件,设置数据库连接信息,以及实体类和表的映射文件(.hbm.xml)。 三、Entity类与表的映射 在Hibernate中,每一个数据库表都...
1. Hibernate 是一种开源的持久层框架,提供了一个高效的数据访问机制,能够将 Java 对象与数据库表进行映射。 2. MyEclipse 是一个集成开发环境(IDE),提供了丰富的开发工具和插件,包括数据库管理、代码编辑、...
【精通Hibernate:Java对象持久化技术】主要涵盖了Java应用程序的分层体系结构、软件模型以及对象持久化的概念,特别是如何使用Hibernate这一ORM框架进行持久化操作。以下是详细的知识点解析: 1. **应用程序分层...