HIbernate的“1+N”问题

HibernateTest.java

代码:

/**
 *
 */
package com.b510.examples;

import java.util.Iterator;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author XHW
 *
 * @date 2011-7-18
 *
 */
public class HibernateTest {
 public static void main(String[] args) {
  new HibernateTest().update();
 }

 public void update() {
  Session session = HibernateSessionFactoryUtil.getSessionFactory()
    .getCurrentSession();
  Transaction tx = session.beginTransaction();

  Query query = session.createQuery("from Product");
  
  Iterator it=query.iterate();
  while(it.hasNext()){
   Product p=(Product)it.next();
   System.out.println("id:"+p.getId()+"   name:"+p.getName());
  }
  tx.commit();
 }

}

运行效果:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
    select
        product0_.id as col_0_0_
    from
        users.product product0_
Hibernate:
    select
        product0_.id as id0_0_,
        product0_.category_id as category2_0_0_,
        product0_.name as name0_0_,
        product0_.price as price0_0_,
        product0_.descripton as descripton0_0_
    from
        users.product product0_
    where
        product0_.id=?
id:1   name:java SE应用程序设计
Hibernate:
    select
        product0_.id as id0_0_,
        product0_.category_id as category2_0_0_,
        product0_.name as name0_0_,
        product0_.price as price0_0_,
        product0_.descripton as descripton0_0_
    from
        users.product product0_
    where
        product0_.id=?
id:3   name:java  web Hibernate
Hibernate:
    select
        product0_.id as id0_0_,
        product0_.category_id as category2_0_0_,
        product0_.name as name0_0_,
        product0_.price as price0_0_,
        product0_.descripton as descripton0_0_
    from
        users.product product0_
    where
        product0_.id=?
id:4   name:HIbernate
Hibernate:
    select
        product0_.id as id0_0_,
        product0_.category_id as category2_0_0_,
        product0_.name as name0_0_,
        product0_.price as price0_0_,
        product0_.descripton as descripton0_0_
    from
        users.product product0_
    where
        product0_.id=?
id:5   name:Hibernate2
Hibernate:
    select
        product0_.id as id0_0_,
        product0_.category_id as category2_0_0_,
        product0_.name as name0_0_,
        product0_.price as price0_0_,
        product0_.descripton as descripton0_0_
    from
        users.product product0_
    where
        product0_.id=?
id:6   name:hibernate3
Hibernate:
    select
        product0_.id as id0_0_,
        product0_.category_id as category2_0_0_,
        product0_.name as name0_0_,
        product0_.price as price0_0_,
        product0_.descripton as descripton0_0_
    from
        users.product product0_
    where
        product0_.id=?
id:7   name:hibernate4
Hibernate:
    select
        product0_.id as id0_0_,
        product0_.category_id as category2_0_0_,
        product0_.name as name0_0_,
        product0_.price as price0_0_,
        product0_.descripton as descripton0_0_
    from
        users.product product0_
    where
        product0_.id=?
id:8   name:hibernate5
Hibernate:
    select
        product0_.id as id0_0_,
        product0_.category_id as category2_0_0_,
        product0_.name as name0_0_,
        product0_.price as price0_0_,
        product0_.descripton as descripton0_0_
    from
        users.product product0_
    where
        product0_.id=?
id:2   name:java WEB开发与实战

我们明明要查询7条记录,但是hibernate用的是8条selelct语句

为什么会出现这种情况呢?

这个主要是hibernate考虑到了一级和二级缓存的效果, 如果缓存中有我们要查询的数据

那么这时我们就不用到数据库中去查询数据,而是直接从缓存中读取我们需要的数据。这就大大

提高了我们程序的运行效率。

但是一旦缓存中没有我们需要的数据,那么这时hibernate就会向数据库发出请求,所以我们看到上面的

运行效果会出现“1+N”的效果;(说明缓存中并没有我们要查询的 数据)

我们要避免这种问题,方法:

测试代码:

HibernateTest.java

代码:

/**
 *
 */
package com.b510.examples;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author XHW
 *
 * @date 2011-7-18
 *
 */
public class HibernateTest {
 public static void main(String[] args) {
  new HibernateTest().update();
 }

 
 public void update() {
  Session session = HibernateSessionFactoryUtil.getSessionFactory()
    .getCurrentSession();
  Transaction tx = session.beginTransaction();

  Query query = session.createQuery("from Product");
  
  List<Product> list=query.list();
  for(Product p:list){
   System.out.println("id:"+p.getId()+"  name :"+p.getName() );
  }
  tx.commit();
 }

}

运行效果:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
    select
        product0_.id as id0_,
        product0_.category_id as category2_0_,
        product0_.name as name0_,
        product0_.price as price0_,
        product0_.descripton as descripton0_
    from
        users.product product0_
id:1  name :java SE应用程序设计
id:2  name :java WEB开发与实战
id:3  name :java  web Hibernate
id:4  name :HIbernate
id:5  name :Hibernate2
id:6  name :hibernate3
id:7  name :hibernate4
id:8  name :hibernate5

我们用List的时候,”1+N“的方法,就会解决,而List是只从数据库中读取数据,不会

到缓存中读取数据,但是list会把从数据库中读取的数据放入到缓存中,而Iterator则是先查询缓存

,如果缓存中有我们需要的数据,那么,这时就读取缓存。如果缓存中没有我们需要的数据,即:没有命中

这时再向数据库发出请求。所以会有”1+N“的运行效果。

原文地址:https://www.cnblogs.com/hongten/p/2111653.html