Hibernate查询实体对象

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);
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值