牛骨文教育服务平台(让学习变的简单)

【含义】

hql,即Hibernate Query  Language。它与我们熟知的sql很类似,它最大的特点就是对查询进行了面向对象的封装,下面会在具体例子中说明。

sql查询的是数据库中的表或字段,而hql是面向对象的,具有继承、多态、关联等特性,他针对的是对象。

【使用】

那么如何使用hql进行查询呢?首先,我们需要宏观看一下hql的几种使用方式:基本使用、外置命名和过滤器。

基本使用即我们将hql语句写在代码中,执行操作。配置文件的方式是将我们所写的hql语句转移到配置文件中,这样就很容易对其进行修改了。第三种过滤器,类似Struts中的Filter过滤器。它对查询的内容进行过滤,在映射文件中定义过滤器,程序中启用过滤器,并为过滤器参数赋值。

【基本使用】

我们先通过例子,了解下hql的基本使用,再介绍其实现原理。

/**
	 * 实体对象查询,
	 */
	public void testquery(){
		Session session=null;
		try{
			//获得Hibernate Session
			session=HibernateUtil.getSession();
			//开启事务
			session.beginTransaction();			
			//以hql语句创建Query对象,Query调用list方法返回全部实例
			List shelfList=session.createQuery("from Shelf").list();		
			//迭代显示数据
			for(Iterator iter=shelfList.iterator();iter.hasNext();){
				Shelf shelf=(Shelf)iter.next();
				System.out.println(shelf.getLocation());
			}
			//提交事务
			session.getTransaction().commit();
		}catch(Exception e){
			//发生异常,事务回滚
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			//关闭Session
			HibernateUtil.closeSession(session);
		}
	}

	/**
	 * 封装类
	 */
	public class HibernateUtil {
		private static SessionFactory factory;
		/**
	 	* 完成sessionFactory的初始化
	 	*/
		static{
		try{
			//读取hibernate.cfg.xml配置文件
			Configuration cfg=new Configuration().configure();
			//建立sessionFactory,可访问mysql
			 factory=cfg.buildSessionFactory();
		}catch(Exception e){
			e.printStackTrace();
		}finally{	
		}
	}
	//获得session
	public static Session getSession(){
		return factory.openSession();
	}
	//关闭session
	public static void closeSession(Session session){
		if(session!=null){
			if(session.isOpen()){
				session.close();
			}
		}
	}
	//返回sessionFactory
	public static SessionFactory getSessionFactory(){
		return factory;
	}
}

Session——对象的增删改查操作

Query,Criteria——执行数据库查询

SessionFactory——初始化Hibernate,创建Session对象。

Configuration——负责配置、启动Hibernate,创建SessionFactory对象。

【外置命名】

外置命名和下面要说的过滤器都是些在配置文件中的,灵活性较好。

需求是,查询Shelf中"code>1"的数据。我们需要在配置文件中,加入hql语句。

<hibernate-mapping >
	<class name="com.hibernate.Shelf" table="t_shelf" >
		<!-- 映射主键 -->
		<id name="code">
			<generator class="native"></generator>
		</id>
	</class>
	<!--外置命名-->
	<query name="queryShelf">
		<![CDATA[
			select s from Shelf s where s.code>?
		]]>
	</query>
</hibernate-mapping>

接下来,代码中就不需要再写hql语句了,但需要注意的是,要使用session的getNameQuery()方法,还要给hql中的问号占位符赋值,这里类似参数化查询的东西,也很好理解。

<span style="white-space:pre">		</span>List shelfList=session.getNamedQuery("queryShelf").setParameter(0, 1).list();
			for(Iterator iter=shelfList.iterator();iter.hasNext();){
				Shelf shelf=(Shelf)iter.next();
				System.out.println(shelf.getLocation());
			}

【过滤器】

过滤器的配置同样也是在配置文件中,这里,我们需要命名过滤器名称和参数名,以及哪个类使用过滤器

<hibernate-mapping >
	<class name="com.hibernate.Shelf" table="t_shelf" >
		<!-- 映射主键 -->
		<id name="code">
			<generator class="native"></generator>
		</id>
		<filter name="testFilter" condition="code < :myParam"></filter>
	</class>
	<!-- 过滤器 -->
	<filter-def name="testFilter">
		<filter-param name="myParam" type="integer"/>
	</filter-def>
</hibernate-mapping>

     代码中也和外置命名类似。

                session.enableFilter("testFilter").setParameter("myParam", 2);//在session中都被启用
		List shelfList=session.createQuery("from Shelf").list();
		for(Iterator iter=shelfList.iterator();iter.hasNext();){
			Book book=(Book)iter.next();
			System.out.println(book.getName());
		}

【小结】

在介绍基本使用方法时,主要是以理解hql的查询原理,不能只停留在会用而已。

外置命名将hql语句抽离出来放到配置文件中,并给了他一个参数名,我们只需要在代码中用这个参数名就可以了。这样如果需求有不太大的变动时,我们就能轻松应对了。

过滤器类似Filter,也是在配置文件中,我们需要开启过滤器,让他帮我们把符合条件的数据过滤出来。但这种方式在面对复杂条件查询的时候可能会不那么方便了。