Hibernate Query数据查询

感情迁移 提交于 2019-12-01 20:02:17

主要由三种查询:HQL查询、Criteria条件查询、SQL查询。

以下分别讲解

1. HQL查询

HQL(Hibernate Query Language)查询提供了更加丰富和灵活的查询特性,因此Hibernate将HQL查询立为官方推荐的标准查询方式。

HQL语法与SQL相似,但HQL是一种面向对象的查询语言,操作的是类、实例和属性等。

HQL是完全面向对象的查询语言,支持继承和多态等特性。

HQL查询步骤

(1) 获得Hibernate Session对象

(2) 设计HQL查询语句

(3) 以HQL查询语句作为参数,调用Session.createQuery(hql)方法创建查询对象

(4) 如果HQL查询语句包含参数,调用Query的setXxxx()方法为参数赋值

(5) 调用Query对象的list等方法遍历查询结果

public class HqlQueryTest{  private void findStudents(){
    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction trans = session.beginTransaction();
    Query query = session.createQuery("FROM Student as stu WHERE stu.studentid=:sid");
    query.setString("sid", "123456");
    List list = query.list();for...
    trans.commit();
    session.close();
    sessionFactory.close();
  }
}

Query接口提供了绑定各种Hibernate映射类型的方法,

如:setBinary()/setString()/setBoolean()/setByte()/setCalendar()/setCharacter()/setDate()/setDouble()/setText()/setTime()/setTimestamp()。

还包含了两个用于实现Hibernate分页的方法:

① setFirstResult(int firstResult):设置返回的结果集从第几条记录开始;

② setMaxResults(int maxResults):设置本次查询返回的结果数;

HQL语法分析

HQL语句本身不区分大小写,但HQL中使用的包名、类型、实例名及属性名都区分大小写。

(1) FROM子句

from Student as st

该子句返回Student持久化类的所有实例,通常推荐起别名;

(2) SELECT子句

select子句选择将哪些对象与属性返回到查询结果集中,当然选择的属性必须是from后持久化类包含的属性。如:

SELECT st.name FROM Student as st

select可以选择任意属性,不仅可以选择持久化类的直接属性,还可以选择引用属性包含的属性(关联内容)。如:

SELECT st.class FROM Student as st

(3) 聚集函数

HQL查询甚至可以返回作用与属性之上的聚集函数的计算结果,HQL支持的聚集函数与SQL完全相同。有5种:

① avg:计算属性平均值;

② count:统计选择对象的数量;

③ max:统计属性值的最大值;

④ min:统计属性值的最小值;

⑤ sum:计算属性值的总和;

如:

SELECT count(*) FROM Student

SELECT max(st.age) FROM Student as st

(4) 多态查询

HQL语句被设计成能理解多态查询,Hibernate可以在from子句中指定任何Java类或接口,其from后跟的持久化类名不仅会查询出该持久化类的全部实力,还会查询出该类中子类的全部实例。

如:FROM Student as st    //该查询语句不仅会查询出Student的全部实例,还会查询出Student的子类

(5) WHERE子句

where子句用于筛选选中的结果,以缩小选择的范围。

如: FROM Student as st WHERE st.name LIKE “张%”

where子句中的属性表达式必须以基本类型或java.lang.String结尾,不要使用引用类型属性结尾。

如Student有class属性,class有classname属性:

FROM Student as st WHERE st.class.Classname LIKE “td%”  //正确

FROM Student as st WHERE st.class LIKE “td%”                   //不正确

(6) 表达式

HQL的表达式非常多,其where子句后支持的运算符也很多,不仅包括SQL的运算符,也包括EJB-QL的运算符等。

在where子句中允许使用的表达式包括大多数可以在SQL中使用的表达式。

· 数学运算符: + 、-、*、/  等

· 二进制比较运算符: =、<=、>=、<>、!=、like 等

· 逻辑运算符:and、or、not 等

· 判断字:in、not in、between、is null、is not null、is empty、is not empty、memberof、not memberof 等

· 条件判断:case、case…when…then…else…end 等

· 字符串连接符:value1 || value2或使用函数 concat(value1, value2)

· 时间操作函数:currentDate、currentTime、currentTimestamp、second、minute、hour、day、month、year 等

· HQL还支持EJB-QL3.0所支持的函数或操作substring、trim、lower、upper、Length、locate、abs、sqrt、bit_length和nullif 等

· 支持数据库的类型转换函数,如cast(…as….),第二个参数是Hibernate的类型名,或者extract(…from…),前提是底层数据库支持ANSI cast和extract

· 如果底层数据库支持单行函数sign、trunk、rtrim()、sin,则HQL语句也可以完全支持

· HQL语句支持使用“?”作为参数占位符,这与JDBC的参数占位符一致,也可以使用命名参数展位符号,方法是在参数名前加冒号“:”,如 :username、:xxx等

· 可在where子句中使用SQL常量,如“tfnew21”、66、”2009-04-21”等

· 还可以在HQL语句中使用Java public static final常量,如CC.Color.TABBY

在这些结构变量中:size、elements、ndices、minindex、maxindex、minelement、maxelement等只能在where子句中使用。

where子句中,有序集合的元素(arrays、lists、maps)可以通过“[]”运算符访问。用法如下:

FROM Student as st where st.class[0].classname is not null

group by子句返回聚集值(Aggregate Values)的查询可以按照一个返回的类或组件(Components)中的任何属性(Property)进行分组,可以对持久化类或引用属性的属性进行分组,分组时可使用group by子句。如下:

SELECT st.age, count(st.name) FROM Student as st GROUP BY st.age

类似于SQL的规则,出现在select后的属性要么出现在聚集函数中,要么出现在group by的属性列表中。

having子句用于对分组进行过滤,having子句只能在有group by子句时才可以使用。如:

SELECT st.age, count(st.name) FROM Student as st GROUP BY st.age HAVING st.age BETWEEN 21 AND 25;

根据查询返回的列表(list),可以按照一个返回的类或组件中的任何属性用order by子句进行排序

可以使用ASC(升序)、DESC(降序)指定排序规则,没有指定则默认采用升序规则。如:

FROM Student as st ORDER BY st.age DESC

group by和order by子句中都不能包含算数表达式

对于集合属性,Hibernate默认采用延迟加载策略

例如,对于持久化类Student,有集合属性class,加载Student实例时,默认不加载class属性。如果Session被关闭,则Student实例将无法访问关联的class属性。

为了解决该问题,可以在Hibernate映射文件中取消延迟加载,或者使用fetch jion。如:

FROM Student as st FETCH JOIN st.class&#160;&#160;&#160; //此处的fetch语句将会初始化Student的class集合属性

如果使用了属性级别的延迟加载,可以用fetch all properties来强制Hibernate立即获取那些原本需要延迟加载的属性。如:

FROM Student FETCH ALL PROPERTIES WHERE age>12 ORDER BY age

HQL查询还支持查询所用的HQL语句放入配置文件中,而不是代码中。通过这种方式,可以大大提高程序设计的灵活度。如下:

<query name="getStudent”>

&#160; FROM Student FETCH ALL PROPERTIES WHERE age>? ORDER BY age

</query>

在程序中调用命名查询的方法为:

Query query = session.getNamedQuery(“getStudent”);

query.setInteger(0, 21);

&#160;

2. Creteria条件查询

条件查询是更具面向对象特色的数据查询方式,通过以下三个类完成:

· Creteria:代表一次查询

· Criterion:代表一个查询条件

· Restrictions:产生查询条件的工具类

执行条件查询的步骤:

(1) 获得Hibernate的Session对象

(2) 以Session对象创建Criteria对象

(3) 增加Criterion查询条件

(4) 执行Criteria的list等方法返回结果集

如:

//增加的限制条件必须是Student已经存在的属性

Criteria cri = session.createCriteria(Student.class);

cri.add(Restrictions.gt(“studentid”, new Integer(123)));

List list = cri.list();

在条件查询中,Criteria接口代表一次查询,该查询本身不具备任何的数据筛选功能。

调用createCriteria(Class class)方法对某个持久化类创建条件查询实例。

Criteria常用方法

Criteria add(Criterion criterion):增加查询条件;

Criteria addOrder(Order order):增加排序规则;

List list():返回结果集;

分页查询用的两个方法

Criteria setFirstResult(int firstResult):设置查询返回的第一行记录;

Criteria setMaxResult(int maxResult):设置查询返回的记录数;

Criterion接口代表一个查询条件,该查询条件由Restrictions负责产生,而Restrictions是专门用于产生查询条件的工具类,它的方法大部分都是静态方法。

常用的方法有如下几种:

static Criterion allEq(Map propertyNameValues):判断指定属性(由Map参数的key指定)和指定值(由Map参数的value指定)是否完全相等;

static Criterion between(String propertyName, Object obj1, Object obj2):判断属性值是否在某个值范围之内;

static Criterion ilike(String propertyName, Object value):判断属性值是否匹配某个字符串;

static Criterion ilike(String propertyName, String value, MatchMode matchMode):判断属性值是否匹配某个字符串,并确定匹配模式;

static Criterion in(String propertyName, Collection values):判断属性值是否在某个集合内;

static Criterion in(String propertyName, Object[] values):判断属性值是否数组元素的其中之一;

static Criterion isEmpty(String propertyName):判断属性值是否为空;

static Criterion isNotEmpty(String propertyName):判断属性值是否不为空;

static Criterion isNull(String propertyName):判断属性值是否不为空;

static Criterion isNotNull(String propertyName):判断属性值是否不为空;

static Criterion not(Criterion expression):对Criterion求否;

static Criterion sizeEq(String propertyName, int size):判断某个属性的元素个数是否与size相等;

static Criterion sqlRestriction(String sql):直接使用SQL语句作为筛选条件;

static Criterion sqlRestriction(String sql, Object value, Type type):直接使用带参数占位符的SQL语句作为条件,并指定参数值;

static Criterion sqlRestriction(String sql, Object[] value, Type[] type):直接使用带参数占位符的SQL语句作为条件,并指定多个参数值;

如果需要使用关联类的属性来增加查询条件,则应该对属性再次使用createCriteria方法,用法如下:

session.cerateCriteria(Student.class)

&#160; .add(Restriction.like(“name”, “天风”)).createCriteria(“classes”).add(Restriction.like(“className”, “班级名”)).list();

注意:查询并不是查询class持久化类,而是查询Student持久化类。

&#160;

3. SQL查询

Hibernate还支持使用SQL查询,使用SQL查询可以利用某些数据库的特性,或者用于将原有的JDBC应用移植到Hibernate应用上。

SQL查询是通过SQLQuery接口来表示的,由于SQLQuery接口是Query接口的子接口,因此完全可以调用Query接口的方法。

执行SQL查询的步骤如下:

(1) 获取Hibernate Session对象;

(2) 编写SQL语句;

(3) 以SQL语句作为参数,调用Session的createSQLQuery方法创建查询对象;

(4) 如果SQL语句包含参数,则调用Query的setXxx方法为参数赋值;

(5) 调用SQLQuery对象的addEntity或addScale方法将选出的结果与实体关联;

(6) 调用Query的list方法返回查询的结果集

使用如下:

List list = session.createSQLQuery(“SELECT {st.*} FROM student as st ”).addEntity(“st”, Student.class).list();

如果不使用{st.*}形式,就可让实体别名与表别名互不相同,关联实体的类型时,被关联的类必须有对应的setter方法。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!