`
wlh269
  • 浏览: 453323 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

HQL (二) 实体对象查询

阅读更多
实体对象查询(重要)  
   * N+1问题,在默认情况下使用query.iterate查询,有可能出现N+1问题,所谓的N+1
     是查询对象的时候发出了N+1条sql语句
    1:首先发出一条查询id列表的sql
    N:根据id列表发出n条查询语句

* list和iterate的区别?
   * list在默认情况下,只向缓存中放入数据,而不利用缓存中的数据
   * iterate在默认情况下有N+1问题,如果缓存中存在数据那么会根据id到缓存获取数据
     也就说iterate是利用缓存的
参见:SimpleObjectQueryTest1.java,SimpleObjectQueryTest2.java    

package com.wlh.hibernate;

import java.util.Iterator;
import java.util.List;

import junit.framework.TestCase;

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

public class SimpleObjectQueryTest1 extends TestCase{
  
	public void testQuery1(){
	  Session  session=null;
	  try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			//返回值为实体对象的集合
			//可以省略select语句
			Query query=session.createQuery("from Student");
			List students=query.list();
			for(Iterator iter=students.iterator();iter.hasNext();){
				Student student=(Student)iter.next();
				System.out.println("student="+student.getName());
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
  }
	public void testQuery2(){
		  Session  session=null;
		  try {
				session = HibernateUtils.getSession();
				session.beginTransaction();
				//返回值为实体对象的集合
				//可以省略select语句,实体类可以加别名
				Query query=session.createQuery("from Student s");
				List students=query.list();
				for(Iterator iter=students.iterator();iter.hasNext();){
					Student student=(Student)iter.next();
					System.out.println("student="+student.getName());
				}
				session.getTransaction().commit();
			}catch(Exception e) {
				e.printStackTrace();
				session.getTransaction().rollback();
			}finally {
				HibernateUtils.closeSession(session);
			}
	  }
	
	public void testQuery3(){
		  Session  session=null;
		  try {
				session = HibernateUtils.getSession();
				session.beginTransaction();
				 //返回值为实体对象的集合
				//可以省略select语句,实体类可以用as加别名
				Query query=session.createQuery("from Student as s");
				List students=query.list();
				for(Iterator iter=students.iterator();iter.hasNext();){
					Student student=(Student)iter.next();
					System.out.println("student="+student.getName());
				}
				session.getTransaction().commit();
			}catch(Exception e) {
				e.printStackTrace();
				session.getTransaction().rollback();
			}finally {
				HibernateUtils.closeSession(session);
			}
	  }
	
	public void testQuery4(){
		  Session  session=null;
		  try {
				session = HibernateUtils.getSession();
				session.beginTransaction();
				//返回值为实体对象的集合
				//使用select查询实体对象,必须采用别名
				Query query=session.createQuery("select s from Student as s");
				List students=query.list();
				for(Iterator iter=students.iterator();iter.hasNext();){
					Student student=(Student)iter.next();
					System.out.println("student="+student.getName());
				}
				session.getTransaction().commit();
			}catch(Exception e) {
				e.printStackTrace();
				session.getTransaction().rollback();
			}finally {
				HibernateUtils.closeSession(session);
			}
	  }
}


package com.wlh.hibernate;

import java.util.Iterator;
import java.util.List;

import junit.framework.TestCase;

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

public class SimpleObjectQueryTest2 extends TestCase{
  
	/**
	 * 发出list查询
	 */
	public void testQuery1(){
	  Session  session=null;
	  try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			/**
			 * 采用list查询将会发出一条查询语句,取得Student数据
			 * select student0_.id as id1_, student0_.name as name1_, 
			 * student0_.createTime as createTime1_, student0_.classesid as classesid1_ 
			 * from t_student student0_
			 * 
			 */
			Query query=session.createQuery("from Student");
			List students=query.list();
			for(Iterator iter=students.iterator();iter.hasNext();){
				Student student=(Student)iter.next();
				System.out.println("student="+student.getName());
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
  }
	
	
	/**
	 * 出现N+1问题
	 * 
	 * 发出查询id类表的sql语句:
	 *  select student0_.id as col_0_0_ from t_student student0_
	 *  
	 * 依次发出根据id查询Student的sql语句:
	 * select student0_.id as id1_0_, student0_.name as name1_0_, 
	 * student0_.createTime as createTime1_0_, student0_.classesid as classesid1_0_ 
	 * from t_student student0_ where student0_.id=?
	 * 
	 */
	public void testQuery2(){
		  Session  session=null;
		  try {
				session = HibernateUtils.getSession();
				session.beginTransaction();
				
				Query query=session.createQuery("from Student");
				Iterator iter=query.iterate();
				while(iter.hasNext()){
					Student student=(Student)iter.next();
					System.out.println("student="+student.getName());
				}
				session.getTransaction().commit();
			}catch(Exception e) {
				e.printStackTrace();
				session.getTransaction().rollback();
			}finally {
				HibernateUtils.closeSession(session);
			}
	  }
	  
	
	/**
	 * 先发出list查询,再发出iterate查询
	 */
	public void testQuery3(){
		Session  session=null;
		try {
				session = HibernateUtils.getSession();
				session.beginTransaction();
				Query query=null;
				
				 query=session.createQuery("from Student");
				List students=query.list();
				for(Iterator iter=students.iterator();iter.hasNext();){
					Student student=(Student)iter.next();
					System.out.println("student="+student.getName());
				}
				System.out.println("===============================");
				/**
				 * 不会出新N+1问题
				 * 
				 * 因为list操作已经将对象放到了一级缓存中(session级缓存),所以在使用Iterate操作的时候
				 * 它会发出根据id查询的语句,取得id列表,再根据id到缓存中获取数据,只有在缓存中找不到相应的数据
				 * 才会发出sql语句到数据库中查询
				 */
			    query=session.createQuery("from Student");
				Iterator iter=query.iterate();
				while(iter.hasNext()){
					Student student=(Student)iter.next();
					System.out.println("student="+student.getName());
				}
				session.getTransaction().commit();
			}catch(Exception e) {
				e.printStackTrace();
				session.getTransaction().rollback();
			}finally {
				HibernateUtils.closeSession(session);
			}

}
	
	/**
	 * 发出两次list查询
	 */
	public void testQuery4() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			List students = session.createQuery("from Student").list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			System.out.println("------------------------------------------------");
			
			/**
			 * 再次发出查询语句
			 * 
			 * 在默认情况下list每次都会向数据库发出查询对象的sql,除非配置了查询缓存,所以下面的list
			 * 操作,虽然在一级缓存中已经有了对象数据,list不会利用缓存中的数据,而再次发出查询sql
			 * 
			 * list在默认情况下,只向缓存中放入数据,而不利用缓存中的数据
			 */
			students = session.createQuery("from Student").list();
			
			for (Iterator iter =students.iterator(); iter.hasNext();) {
				Student student = (Student)iter.next();
				System.out.println(student.getName());
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}			
	
}

分享到:
评论

相关推荐

    HQL 语法总结 实体查询

    #### 二、实体查询的高级用法 除了基本的实体查询之外,HQL还支持更复杂的查询,例如: - **查询所有对象**: ```java hql = "from java.lang.Object"; ``` 这条语句将会返回数据库中所有表的数据记录。然而...

    HQL查询pdf资料

    HQL(Hibernate Query Language)是一种面向对象的查询语言,它提供了与SQL类似的功能,但更贴近于面向对象编程的思维方式。HQL允许开发人员以一种更自然的方式查询数据库,同时保持了Java对象模型的一致性。 #### ...

    HQL.pdf数据查询语句

    HQL与SQL语法类似,但它理解Java实体和属性,因此HQL查询的对象是Java类而不是数据库中的表。 首先,HQL的基本查询语句包括从特定实体类中查询记录。例如,查询一个名为User的实体类的所有记录,可以使用以下语句:...

    hibernateHQL关联查询

    在实际开发中,HQL关联查询的应用场景非常广泛,特别是在需要跨多个实体进行数据检索的情况下。例如,在电子商务系统中,我们需要获取用户信息及其相关的订单信息时,就可以利用HQL关联查询来简化这一过程。此外,当...

    HQL是hibernate自己的一套查询

    `Example`是另一种用于查询的方式,主要用于匹配实体对象的某些属性。 ```java Session session = HibernateUtil.getSession(); List<User> users = session.createCriteria(User.class) .add(Example.create(user...

    HQL多对多的查询语句分析

    HQL(Hibernate Query Language)是Hibernate框架提供的面向对象的查询语言,它允许开发者用类名和属性名称来执行SQL查询,使得代码更加易读且与数据库无关。本文将深入分析HQL在处理多对多关系时的查询语句及其应用...

    hibernate的HQL的模糊查询

    HQL是一种面向对象的查询语言,它的语法结构与SQL类似,但更关注于对象和实体,而不是数据库表和列。HQL允许开发者直接操作Java对象,避免了直接编写SQL语句的麻烦,并且支持跨数据库的移植性。 二、HQL模糊查询...

    HQL与QBC的查询条件.doc

    QBC是一种基于实例的查询方式,通过提供一个实体对象实例作为查询的模板,Hibernate会自动根据对象的属性生成相应的查询语句。QBC的主要优势在于它的直观性和简单性。QBC中的运算符与HQL中的对应,例如,通过调用...

    hibernate hql各类查询范例

    第二个示例展示了如何使用 HQL 进行参数化查询。方法名为 `getDutyManOfGroup`,其中 HQL 语句如下: ```java "from syidt.modules.grp.basegrp.persistence.Person as person where person.theGroup.groupOID=?"; `...

    HQL 查询语言基础 二

    ### HQL 查询语言基础二 #### 一、FROM 子句 在HQL查询语言中,`FROM`子句用于指定查询数据来源的实体或表。例如: ```hql FROM Person as p ``` 这里的`Person`表示的是一个持久化类,即ORM映射中的实体类。`as...

    Hql多结果集

    执行上述HQL语句后,返回的结果将会是一个`List`集合,其中每个元素都是一个对应的实体对象。 ##### 2. 查询单个实体 如果只需要查询表中的某一个实体,可以通过添加`WHERE`子句来实现: ```hql FROM 实体名 ...

    Hibernate之HQL查询

    FROM子句指定要查询的对象,可以是一个实体类,也可以是多对一、一对多、多对多关联的类。例如: ```sql SELECT c FROM Course c JOIN c.students AS s WHERE s.name = '张三' ``` 此查询将返回所有张三选修的课程...

    HQL语法入门学习HQL语法入门学习

    - `from`关键字用于指定要查询的对象,`类名`是你希望查询的实体类,`别名`是可选的,可以更方便地引用查询结果中的对象。 2. **条件查询**: `where 条件表达式` - `where`后面可以跟任何合法的条件表达式,包括...

    HibernateUtil分装完整版HQL查询

    HQL是Hibernate提供的面向对象的查询语言,类似于SQL,但它是针对对象模型而非关系数据库设计的。HQL允许开发者以类和属性的名称进行查询,而不是表和列名,这使得代码更具可读性和可维护性。例如,你可以通过HQL...

    Hibernate教程(数据查询)HQL,PDF格式

    在数据查询方面,Hibernate提供了多种查询方式,其中HQL(Hibernate Query Language)是一种基于SQL的领域查询语言,它允许开发者以面向对象的方式编写查询语句,而无需直接处理复杂的SQL语句。本文将深入探讨...

    hql语句大全hql语句大全

    此语句将查询`Cat`实体,并将结果集中的每个实例映射为一个名为`cat`的对象。 ##### 3. JOIN子句 JOIN子句用于处理实体之间的关联关系,如一对一、一对多等。HQL支持内连接、左外连接、右外连接和全连接,其语法...

Global site tag (gtag.js) - Google Analytics