N+1问题
list()获得对象:
/**
* 只会与数据库交互一次,查询出来全部信息
*/
List<XXX> ls = (List<XXX>)session.createQuery("from XXX").setFirstResult(0).setMaxResults(30).list();
Iterator<XXX> xxx = ls.iterator();
for(;xxx.hasNext();)
{
XXX xxx = (XXX)xxx.next();
System.out.println(xxx.getName());
}
iterator()获得对象
/**
* 如果使用iterator方法返回列表,对于hibernate而言,它仅仅只是发出取id列表的sql
* 在查询相应的具体的某个信息时,会发出相应的SQL去取相应信息
* 这就是典型的N+1问题
* 存在iterator的原因是,有可能会在一个session中查询两次数据,如果使用list每一次都会把所有的对象查询上来
* 而是要iterator仅仅只会查询id,此时所有的对象已经存储在一级缓存(session的缓存)中,可以直接获取
*/
Iterator<XXX> xxx= (Iterator<XXX>)session.createQuery("from XXX").setFirstResult(0).setMaxResults(30).iterate();
for(;xxx.hasNext();)
{
XXX xxx = (XXX)xxx.next();
System.out.println(xxx.getName());
}
Hibernate一级缓存又称为“Session的缓存”。
Session内置不能被卸载,Session的缓存是事务范围的缓存(Session对象的生命周期通常对应一个数据库事务或者一个应用事务)。
一级缓存中,持久化类的每个实例都具有唯一的OID。
Hibernate二级缓存又称为“SessionFactory的缓存”。
由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。
第二级缓存是可选的,是一个可配置的插件,默认下SessionFactory不会启用这个插件。
Hibernate提供了org.hibernate.cache.CacheProvider接口,它充当缓存插件与Hibernate之间的适配器。