数据查询与检索是Hibernate框架中的一个亮点,相对其他ORM框架实现而言,Hibernate框架提供了灵活多样
的查询机制。
标准化对象查询(Criteria Query)是以对象的方式进行查询,将查询语句封装为对象操作。它的优点就是可读性
好,符合Java 程序员的编码习惯。缺点就是不够成熟,不支持投影(projection)或统计函数(aggregation)。
Hibernate语言查询(Hibernate Query Language,HQL),它是完全面向对象的查询语句,查询功能非常强
大,具备多态、关联等特性,因此也是Hibernate官方推荐使用HQL进行查询。
当然Native SQL Queries(原生SQL查询),直接使用标准SQL语言或跟特定数据库相关的SQL进行查询。
标准化对象查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL查询提供了更加丰富的和
灵活的查询特性,因此Hibernate框架将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询
的所有功能的前提下,提供了类似标准SQL语句的查询方式,同时也提供了更加面向对象的封装。
完整的HQL语句形式如下:
select/update/delete…… from …… where …… group by …… having …… order by …… asc/desc
其中的update/delete为Hibernate3中所新添加的功能,可见HQL查询非常类似于标准SQL查询。而且from子
句是HQL最基本的查询子句,也是一个HQL语句中必不可少的语句。
HQL与SQL重要的区别:
HQL是面向对象的查询语言,而SQL是面向数据表的查询语言。
HQL查询的是映射配置的持久化类及其属性,而SQL查询的是数据库中的数据表的数据。
初学HQL注意的问题:
HQL是面相对象的查询语言,对Java类大小写敏感;
SQL与HQL形式相似,本质不同;
HQL对关键字不区分大小写,推荐是小写;
简单例子:查询用户名以"张"开头的所有用户。
Criteria criteria = session.createCriteria(User.class);
criteria.add(Expression.like("name","张%"));
List users = criteria.list();
from子句是HQL语句最简形式,在SQL语句中select子句和from子句是必须的,而在HQL中只需要一个简单的
from子句即可被HIbernate解析执行。from子句指定了HQL语句查询主体,也就是指定了持久化类及其属性,默认
就是查询指定持久化类的所有属性信息。
from子句中不需要引入持久化类的全限定名,直接引入类名即可,因为HIbernate框架使用auto-import(自动
导入)功能。
from子句中别名的使用,为被查询的类指定别名,通常使用as关键字指定,也可以省略;在HQL语句其它部分通
过别名引用该类。
简单实例:
实体类Seller对应的数据表Seller数据:
查询代码:
/*
* 使用持久化类名是使用持久化类的的默认构造器
*/
@Test
public void testFromClause(){
//直接使用持久化类名
//String hql = " from Seller";
//使用持久化类全限定名
//String hql = " from com.demo.entity.Seller";
//使用as关键字命名表别名
//String hql = " from Seller as s";
//不使用as关键字命名表别名
String hql = " from Seller s";
Query query = session.createQuery(hql);
List sellers = query.list();
for(Seller seller : sellers){
System.out.println("name:"+seller.getName());
}
}
查询结果:
以Object[]形式返回选择的属性
select子句中未指定返回数据类型,默认是Object[]
简单实例:
/*
* 1.name 2.tel 3.address
* 多个属性组成对象数组
*/
@Test
public void testSelectClauseObjectArray(){
String hql = " select s.name,s.tel,s.address from Seller s";
Query query = session.createQuery(hql);
List
查询结果:
如果选择的属性只有一个,那么默认返回的就是一个Object。
实例:
/*
* name
* 单个属性只是一个Object对象,也可以直接返回属性所对应的对象
*/
@Test
public void testSelectClauseObject(){
String hql = " select s.name from Seller s";
Query query = session.createQuery(hql);
List
查询结果:
以List形式返回选择的属性
select子句中使用new list指定
简单实例:
/*
* 1.name 2.tel 3.address
* 指定返回List集合
*/
@SuppressWarnings("rawtypes")
@Test
public void testSelectClauseList(){
String hql = "select new list(s.name,s.tel,s.address) from Seller s";
Query query = session.createQuery(hql);
List lists = query.list();
for(List list : lists){
System.out.println("name : "+list.get(0));
System.out.println("tel:"+list.get(1));
System.out.println("address:"+list.get(2));
}
}
查询结果:
以Map形式返回选择的属性
select子句中使用new map指定,其中key值为索引值,字符串类型
实例:
/*
* 1.name 2.tel 3.address
* 指定返回Map集合
*/
@SuppressWarnings("rawtypes")
@Test
public void testSelectClauseMap(){
//String hql = " select new map(s.name,s.tel,s.address) from Seller s";
//指定返回属性的别名
String hql = " select new map(s.name as name,s.tel as tel,s.address as address) from Seller s";
Query query =session.createQuery(hql);
List
查询结果:
以自定义类型返回选择的属性
持久化类中必须定义对应的构造器,构造器中的参数就是指定返回的属性,select子句中调用定义的构造器
实例:
/*
* 1.name 2.tel 3.address
* 指定返回自定义类型Seller
*/
@Test
public void testSelectClauseSelf(){
String hql = " select new Seller(s.name,s.tel,s.address) from Seller s";
Query query = session.createQuery(hql);
List sellers = query.list();
for(Seller seller : sellers){
System.out.println("name: "+seller.getName());
System.out.println("tel:"+seller.getTel());
System.out.println("address:"+seller.getAddress());
}
}
结果查询:
在这里,需要说明一下持久化类中无参构造方法的必要性,如果在这里定义了自己的构造器,那么就必须在持久
化类中显式指明无参构造器,因为使用from Seller的HQL语句就是默认使用的无参构造器查询。
获取独特的结果——distinct关键字
使用distinct关键字取出查询结果中重复的元素
实体类Customer对应的数据表Customer数据:
实例:
/*
* 使用distinct关键字去除重复的元素
*/
@Test
public void testDistinct(){
//String hql = "select c.sex from Customer c";
String hql = "select distinct c.sex from Customer c";
Query query = session.createQuery(hql);
List
查询结果: