Hibernate HQL中list和iterate的区别

执行HQL查询有两种方法,一种是list方法,另一种是iterate方法。这两种方法到底有什么区别,下面我们通过例子来说明两者的区别。

Company表:

Employee表(employee_company_id为外键)

Company实体类:

import java.util.Set;

public class Company {
    private int companyId;
    private String companyName;
    private Set<Employee> companyEmployees;
    public int getCompanyId() {
        return companyId;
    }
    public void setCompanyId(int companyId) {
        this.companyId = companyId;
    }
    public String getCompanyName() {
        return companyName;
    }
    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
    public Set<Employee> getCompanyEmployees() {
        return companyEmployees;
    }
    public void setCompanyEmployees(Set<Employee> companyEmployees) {
        this.companyEmployees = companyEmployees;
    }
}

Employee实体类:

public class Employee {
    private int employeeId;
    private String employeeName;
    private Company employeeCompany;
    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
    public Company getEmployeeCompany() {
        return employeeCompany;
    }
    public void setEmployeeCompany(Company employeeCompany) {
        this.employeeCompany = employeeCompany;
    }
}

Company hbm配置:

<hibernate-mapping>
    <class name="com.jaeger.hibernatetest.day7.lazy.Company" table="company">
        <id name="companyId" column="company_id">
            <generator class="native"></generator>
     </id>

     <property name="companyName" column="company_name"/>
      <set name="companyEmployees" cascade="all">
           <key column="employee_company_id"></key>
        <one-to-many class="com.jaeger.hibernatetest.day7.lazy.Employee"/>
      </set>
   </class>
</hibernate-mapping>

Employee hbm配置:

<hibernate-mapping>
    <class name="com.jaeger.hibernatetest.day7.lazy.Employee" table="employee">
       <id name="employeeId" column="employee_id">
         <generator class="native"></generator>
     </id>

        <property name="employeeName" column="employee_name"/>
        <many-to-one name="employeeCompany" class="com.jaeger.hibernatetest.day7.lazy.Company" 
            foreign-key="fk_employee_company" column="employee_company_id"
            cascade="save-update">
        </many-to-one>
   </class>
</hibernate-mapping>

1. list方法
list方法会向数据库发出sql语句,一次查询出所有满足HQL语句的记录,测试方法如下:

List<Employee> allEmployees = session.createQuery("from Employee").list(); //A
for(Employee employee : allEmployees){
    System.out.println(employee.getEmployeeId());
    System.out.println(employee.getEmployeeName());
}

A:这里会发出sql去查询满足HQL条件的所有employee信息,sql如下:

select
     employee0_.employee_id as employee1_1_,
     employee0_.employee_name as employee2_1_,
     employee0_.employee_company_id as employee3_1_ 
  from
     employee employee0_

2. iterate方法

iterate方法只会查询表的主键返回的是Iterator对象,当我们真正使用对象时,才会用主键去数据库查找其他信息,测试方法如下:

Iterator<Employee> allEmployees = session.createQuery("from Employee").iterate(); //A
while(allEmployees.hasNext()){
    Employee employee = allEmployees.next();
    System.out.println(employee.getEmployeeId()); //B
    System.out.println(employee.getEmployeeName()); //C
}

A:这里会先去查询employee表的所有主键,sql如下:

select
     employee0_.employee_id as col_0_0_ 
  from
     employee employee0_

B:这里会返回employee id,但并不会向数据库发出sql语句,因为employee id为主键,上面已经查询出来了,使用不用在去数据库查询。

C:这里才会根据每个employee id再次去数据库查询其他信息。

select
     employee0_.employee_id as employee1_1_0_,
     employee0_.employee_name as employee2_1_0_,
     employee0_.employee_company_id as employee3_1_0_ 
  from
     employee employee0_ 
 where
     employee0_.employee_id=?

总结:list方法只会查询一次,而iterate方法先会去查所有主键,再遍历主键去查询其他信息,所以总共会查询N+1次。当我们的程序要根据主键再来做不同处理的话,比如:if(employee.getEmployeeId() == 1),应该使用iterate,因为只取主键的话不会再发sql语句了,也会使加载数据大大减少。但如果要遍历所有信息的话,应该用list方法,可以一次加载所有信息,不用频繁的与数据库通信。

时间: 2024-10-13 09:21:56

Hibernate HQL中list和iterate的区别的相关文章

Hibernate HQL中的子查询

子查询是SQL语句中非常重要的功能特性,它可以在SQL语句中利用另外一条SQL语句的查询结果,在Hibernate中HQL查询同样对子查询功能提供了支持. 如下面代码所示: List list=session.createQuery("from Customer c where 1<(select count(o) from c.orders o)").list(); 上面的程序查询订单数超过1的所有客户,因此和上面子查询HQL语句对应的SQL语句为: Select * from

Hibernate之查询中get()和load()的区别,list()和iterate()的区别

[Hibernate]之查询中get()和load()的区别,list()和iterate()的区别 list()查询 //一次性把数据对象取出来 @Test public void findTestList(){ Session s=sessionFactory.getCurrentSession(); s.beginTransaction(); List<Person> persons=s.createQuery("from Person").list(); for(P

Hibernate框架中的HQL注入漏洞

 Hibernate是一种ORMapping框架,内部可以使用原生SQL还有HQL语言进行SQL操作. 所谓的HQL注入,就是指在Hibernate中没有对数据进行有效的验证导致恶意数据进入应用程序中造成的. 请看这段代码: Input参数即可造成注入. 不过在Hibernate中,一般都是在createQuery中使用PDO,使用setString填充占位符进行sql语句的拼接,如果是这样的话,自然就不存在SQL注入,但是不排除有人像上面的图片中的写法. 正常情况下: Sqlin参数存在注

Hibernate中load()和get()的区别,lazy加载和Eager加载的区别

Hibernate中load()和get()的区别: get():是直接操作数据库,通过id获取数据封装对象,如果没有数据则返回null: load():先在session缓存中查询,如果缓存中不存在,则延迟从数据库中查询,没发现符合条件的记录,则会抛出一个ObjectNotFoundException.在延迟查询中如果session关闭则会抛出no session异常 Hibernate中lazy加载和Eager加载的区别: Eager加载:将当前表和关联的其它表一并查询出来,select的语

Spring Data之@Query中的org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML

1. 环境准备 Spring , Spring Data, JPA, HIbernate, JDK 1.7 2.  问题提出 在使用Spring Data 来更新数据之时,爆出了如下错误信息: @Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2") public void updateAllUsers(long state, long serverid); 错误信息如下: org.springframework.d

Hibernate中saveOrUpdate()和merge()的区别

Hibernate中saveOrUpdate()和merge()的区别 this.getSession().merge(obj); this.getSession().saveOrUpdate(obj); saveOrUpdate(): saveOrUpdate()基本上就是合成了save()和update() 1.如果该po对象已经在本session中持久化了,在本session中执行saveOrUpdate不做任何事 2.如果savaOrUpdate(新po)与另一个与本session关联的

hibernate查询语句hql中的占位符?参数与命名参数:name设值方式搞混

先贴出异常 Struts has detected an unhandled exception: Messages: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 1 File: org/hibernate/engine/query/spi/ParameterMetadata.java Stacktraces org.h

hibernate中update与saveOrUpdate的区别

[转]hibernate中update与saveOrUpdate的区别 分类: Hibernate总结 2009-11-17 00:04 2121人阅读 评论(0) 收藏 举报 hibernatesession数据库javadaoapplication 先来点概念: 在Hibernate中,最核心的概念就是对PO的状态管理.一个PO有三种状态: 1.未被持久化的VO 此时就是一个内存对象VO,由JVM管理生命周期 2.已被持久化的PO,并且在Session生命周期内 此时映射数据库数据,由数据库

Hibernate Hql 总结

1.from子句 Hibernate中最简单的查询语句的形式如下: from eg.Cat该子句简单的返回eg.Cat类的所有实例. 通常我们不需要使用类的全限定名, 因为 auto-import(自动引入) 是缺省的情况. 所以我们几乎只使用如下的简单写法: from Cat大多数情况下, 你需要指定一个别名, 原因是你可能需要 在查询语句的其它部分引用到Cat from Cat as cat这个语句把别名cat指定给类Cat 的实例, 这样我们就可以在随后的查询中使用此别名了. 关键字as