(

产生的原因:当一对多或多对多的映射关系下,当在一方添加或修改数据时,一方集合属性中的多方都要发生变化;先select语句,再update语句.当一方集合属性中的数据有很多时,对应的update语句就有很多.

解决方案:

1.在集合配置上加inverse=”true”.表示一方放弃维护外键关系,但不会影响查询,这样不管一方怎么变化,都不会影响多方.

2.在set标签中添加lazy=”true”,目的就是当需要多方数据时才去查询.lazy属性放在class标签后表示跟load方法有关.

)

/**
* Query接口的list()方法不会从Session缓存中读取数据,这样导致效率比较低
*/
@Test
public void testFindAll_list() {
  // 1.获取Session对象
  Session session = HbnUtils.getSession();
  try {
    // 2.开启事务
    session.beginTransaction();
    // 3.执行操作
    //第一次查询
    String hql = "from Student";
    List<Student> list = session.createQuery(hql).list();
    for (Student student : list) {
      System.out.println(student);
    }
    //第二次查询
    List<Student> list2 = session.createQuery(hql).list();//这里还是从数据库读取的数据
    for (Student student : list2) {
      System.out.println(student);
    }
    // 4.事务提交
    session.getTransaction().commit();
    } catch (Exception e) {
      e.printStackTrace();
      // 5.事务回滚
      session.getTransaction().rollback();
  }
}

 

/**
* Query接口的iterate()方法会从Session缓存中读取数据
*/
@Test
public void testFindAll_iterate() {
  // 1.获取Session对象
  Session session = HbnUtils.getSession();
  try {
    // 2.开启事务
    session.beginTransaction();
    // 3.执行操作
    //第一次查询
    String hql = "from Student";
    //Iterator it = session.createQuery(hql).iterate();//n+1问题就是由iterate引起的
    //while(it.hasNext()){
    //  System.out.println(it.next());
      // }

    //避免n+1问题 :第一次查询使用list()而不是iterate()
    List<Student> list = session.createQuery(hql).list();
    for (Student student : list) {
      System.out.println(student);
    }


    System.out.println("------------");
    //第二次查询
    Iterator it2 = session.createQuery(hql).iterate();
    while(it2.hasNext()){
      System.out.println(it2.next());
    }
    // 4.事务提交
    session.getTransaction().commit();
  } catch (Exception e) {
    e.printStackTrace();
    // 5.事务回滚
    session.getTransaction().rollback();
  }
}