Hibernate中List和Iterate的区别

Hibernate中List和Iterate的区别

Hibernate在国内没有国外那么火,国内的ORM框架几乎被Mybatis霸占,因为Hibernate的底层采用了大量的反射机制与缓存机制,所以对很多的地方都需要进行调优,而Mybatis的操作几乎是傻瓜式。Hibernate有时候会因一点点配置的差异会导致项目响应出现极大的反差,今天我们就来说一下Hibernate中Query的两个获取对象集合的方法

Query中有两个获取对象集合的方法分别为 List 和 Iterate 

List和Iterate的不同

List 和 Iterate 的不同主要是在一对多和多对一的时候体现出来的。

1、获取的方式不同

// List的获取方式
List<Invitation> list = query.list();

// Iterator的获取方式
Iterator<Invitation> it = query.iterate();

2、List 只是查询一级缓存,而Iterate还会查询二级缓存

3、List方法返回的对象都是实体对象,而Iterator返回的是代理对象

4、session中的List第二次发出请求,仍会到数据库査询,而Iterate 第二次,首先找session 级缓存

List和Iterate的利与弊

List()方法在执行时,现在一级缓存中找,没有再立马到数据库中查询所需要的数据。对于List()方式的查询通常只会执行一条SQL语句,List()方法会一次取出所有的结果集对象,以及对象属性多对一的属性数据,就是会依据查询的结果初始化所有的结果集对象(多对一或者一对多)。如果在结果集的数据非常庞大的时候,就会占据大量的内存,甚至会导致内存的溢出。

Iterator()方法则是先执行得到对象ID的查询,然后在根据每个ID值去取得所要查询的对象。而对于iterator()方法的查询则可能需要执行N+1条SQL语句(N为结果集中的记录数),Iterator()方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象,如果你需要使用这个对象中的对象值,那么它才会到数据库中查询,而且一次在访问中可以控制缓存中对象的数量,以避免占用过多的缓存,导致内存溢出情况的发生。

实际调试的数据

测试环境:IDEA、Hibernate 5.4.10.Final、JUNIT 4.0、MySQL 8.0

list获取数据的调试记录

测试代码:

@Test
    public void testGetList() {
        Session session = sf.openSession();

        String hql = "from Invitation";
        // list()方法在执行时,直接运行查询结果所需要的查询语句。
        // 对于list()方式的查询通常只会执行一个SQL语句
        // list()方法会一次取出所有的结果集对象,而且他会依据查询的结果初始化所有的结果集对象。
        // 如果在结果集非常庞大的时候会占据非常多的内存,甚至会造成内存溢出的情况发生。
        Query<Invitation> query = session.createQuery(hql, Invitation.class);

        List<Invitation> list = query.list();
        for (Invitation l : list) {
            System.out.println(l);
        }
        session.close();
    }

Iterate的调试记录

测试代码:

@Test
    public void testGetIterate() {
        Session session = sf.openSession();
        // HQL 语句
        String hql = "from Invitation";
        // 获取Query对象
        // iterator()方法则是先执行得到对象ID的查询,然后在根据每个ID值去取得所要查询的对象。
        // 而对于iterator()方法的查询则可能需要执行N+1条SQL语句(N为结果集中的记录数).
        // iterator()方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象。
        // 一次在访问中可以控制缓存中对象的数量,以避免占用过多的缓存,导致内存溢出情况的发生。
        Query<Invitation> query = session.createQuery(hql, Invitation.class);
        Iterator<Invitation> iterate = query.iterate();
        Invitation invitation;
        while (iterate.hasNext()) {
            System.out.println("暂时没有往数据库中查询数据");
            invitation = iterate.next();
            System.out.println(invitation);
        }
        session.close();
    }

发布了28 篇原创文章 · 获赞 2 · 访问量 936

猜你喜欢

转载自blog.csdn.net/TanGuozheng_Java/article/details/103824894