我们在学习Hibernate的时候就说过,ORM的优点之一就是可以让你专心于面向对象,在java类中,尽可能的减少使用sql语句的频率,hibernate对数据的检索主要有五种方式,分别是“导航对象图检索方式”,“oid检索方式”“hql检索方式”“QBC检索方式”和“本地SQL检索方式”。
我们今天主要尝试的就是HQL检索方式。
首先我们要想,为什么要去学HQL检索方式呢?也就是HQL检索方式的优点。
HQL是面向对象的查询语言,他和SQL查询语言有些相似(这使得我们可以很快的进行理解与编码),但是与SQL不同的是HQL使用的是类、对象和属性的概念,没有表与字段的概念。HQL是官方推荐的查询语言,也是使用最广范的一种检索方式。
它有如下功能
1)在查询语句中设定各种查询条件 : where 过滤
2)支持投影查询, 即仅检索出对象的部分属性
3)支持分页查询
4)支持连接查询
5)支持分组查询, 允许使用 HAVING 和 GROUP BY 关键字
6)提供内置聚集函数, 如 sum(), min() 和 max()
7)支持子查询
8)支持动态绑定参数
9)能够调用 用户定义的 SQL 函数或标准的 SQL 函数
我们只选择几个进行测试。
首先我们要建立一个项目。并且建立pojo类和两个配置文件
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 在控制台显示SQL语句 -->
<property name="show_sql">true</property>
<!-- 连接数据库的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 连接数据库的驱动名 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 连接数据库的URL -->
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/person</property>
<!-- 连接数据库的用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 连接数据库的密码 -->
<property name="hibernate.connection.password">root</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 保证每个线程有一个属于自己的Session对象 -->
<property name = "hibernate.current_session_context_class">thread</property>
<mapping resource="com/Jayson/Entity/Person.hbm.xml"/>
</session-factory>
</hibernate-configuration>
<?xml version="1.0"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.Jayson.Entity">
<class name="Person" table="person" select-before-update="true" dynamic-update="true">
<id name="id" column="id">
<generator class="identity" />
</id>
<property name="name" column="name" length="100"/>
<property name="sex" column="sex" length="100"/>
</class>
</hibernate-mapping>
package com.Jayson.Entity;
public class Person {
private int id;
private String name;
private String sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Person() {
}
public Person(String name, String sex) {
this.name = name;
this.sex = sex;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", sex=" + sex + "]";
}
}
建立好了之后我们写一个单例的sessionfactory,原因在以前的博文讲过,这里就不再提了。
package com.DAO;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static Configuration cfg;
private static SessionFactory sf;
static
{
try {
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static SessionFactory getSessionFactory(){
return sf;
}
}
首先,我们来试一下hql的别名使用,
@Test
//制定别名
public void aliasTest(){
// TODO Auto-generated method stub
SessionFactory sf = null;
Session session = null;
Transaction ts = null;
try {
sf = HibernateUtil.getSessionFactory();
session = sf.getCurrentSession();
ts = session.beginTransaction();
String hql = "from Person as p where p.name ='shi'";
Query query = session.createQuery(hql);
List<Person> ps=query.list();
for (Person person : ps) {
System.out.println(person.toString());
}
} catch (HibernateException e) {
// TODO Auto-generated catch block
if(ts != null)
{
ts.rollback();
}
e.printStackTrace();
}
}
我们发现在一条内容中,其实你想获取的只有几个字段,这时就要应用到投影查询了。
@Test
//投影查询
public void portionQueryTest(){
// TODO Auto-generated method stub
SessionFactory sf = null;
Session session = null;
Transaction ts = null;
try {
sf = HibernateUtil.getSessionFactory();
session = sf.getCurrentSession();
ts = session.beginTransaction();
String hql = "select p.name,p.sex from Person as p";
Query query = session.createQuery(hql);
List<Object[]> list=query.list();
Iterator it = list.iterator();
while(it.hasNext())
{
Object[] obj = (Object[]) it.next();
System.out.println(obj[0]+" "+obj[1]);
}
} catch (HibernateException e) {
// TODO Auto-generated catch block
if(ts != null)
{
ts.rollback();
}
e.printStackTrace();
}
}

我们将查询到的数据放到了一个Object数组中,然后再去输出数组。接下来我们把这个方式再完善一下,让它能对应到我们的类。
@Test
//动态实例查询
public void dynamicQueryTest(){
// TODO Auto-generated method stub
SessionFactory sf = null;
Session session = null;
Transaction ts = null;
try {
sf = HibernateUtil.getSessionFactory();
session = sf.getCurrentSession();
ts = session.beginTransaction();
String hql = "select new Person(p.name,p.sex)from Person as p";
//注意,你要查什么就要有什么样的有参构造方法,方法里的参数不能缺也不能多。
Query query = session.createQuery(hql);
List<Person> list=query.list();
for (Person p : list) {
System.out.println(p.getName()+" "+p.getSex());
}
} catch (HibernateException e) {
// TODO Auto-generated catch block
if(ts != null)
{
ts.rollback();
}
e.printStackTrace();
}
}
接下来时按条件查询;
@Test
//条件查询,按参数位置查询
public void paraQueryTest1(){
// TODO Auto-generated method stub
SessionFactory sf = null;
Session session = null;
Transaction ts = null;
try {
sf = HibernateUtil.getSessionFactory();
session = sf.getCurrentSession();
ts = session.beginTransaction();
String hql = "from Person where name like ?";
Query query = session.createQuery(hql);
query.setString(0, "%er%");
//0 从第0位置开始;
List<Person> list=query.list();
for (Person p : list) {
System.out.println(p.toString());
}
} catch (HibernateException e) {
// TODO Auto-generated catch block
if(ts != null)
{
ts.rollback();
}
e.printStackTrace();
}
}
这次就先尝试这么多。剩下的可以自行了解。