您的位置:首页 > 其它

Hibernate<7> Hibernate的检索方式

2015-10-02 00:00 351 查看
摘要: Hibernate检索方式 HQL QBC QBE等检索方式

HIbernate提供了以下几种检索对象的方式:

①、导航对象图检索方式:根据已经加载的对象,导航到其他对象。例如,对于已经加载的Customer对象,调用它的getOrders().iterator()方法就可以导航到所关联的Order对象。

②、OID检索方式:按照对象的OID来检索对象,session的get()和load()方法提供了这种功能。如果在应用程序中事先知道了OID,就可以使用这种检索对象的方式。

③、HQL检索方式:使用面向对象HQL查询语言,Hibernate提供的Query接口,它是Hibernate提供的专门的HQL查询接口,能够执行各种复杂的HQL查询语句。

④、QBC检索方式:使用QBC(Query By Criteria)API来检索对象,

⑤、本地SQL检索方式。

⑥、QBE检索方式:QBC的子功能。

一、Hibernate检索方式简介:

当直接使用JDBC API查询数据库时,必须在应用程序中嵌入冗长的SQL语句。

1、HQL检索方式(Hibernate Query Language) HQL是面向对象查询语言。

2、QBC检索方式(Query By Criteria) QBC API提供了检索对象的另一种方式,它主要是有Criteria接口、Criterion接口和Expression类组成,它支持在运行时动态生成查询语句。

3、QBE检索方式(Query By Example) 它是QBC的子功能。QBE允许先创建一个对象样板,然后检索出所有和这个样板相同的对象。

4、Sql检索方式:Sql检索方与HQL检索方式都使用Query接口,区别在于SQL检索方式通过Session的createSQLQuery()方法来创建Query对象。

二、HQL检索方式

1、使用别名:

通过HQL检索一个类的实例时,如果查询语句的其他地方需要引用它,应该为这个类指定一个别名,例如:from Customer as customer where customer.name=:name。as关键字用于设定别名,也可以将as关键字省略。

2、多条查询:

HQL和QBC都支持多态查询,多态查询指查询出当前类及所有子类的实例。

3、对查询结果排序

HQL与QBC都支持对查询结果排序,HQL采用order by关键字对查询结果排序,而QBC采用Order类对查询结果排序。

//hql检索方式

Query query=session.createQuery("from Customer customer order by customer.name");

//QBC方式

Criteria criteria=session.createCriteria(Customer.class);

criteria.addOrder(Order.asc("name"));

4、分页查询:

Query和Criteria接口都提供了用于分页显示查询结果的方法:

setFirstResult(int firstResult):设定从哪一个对象开始检索。

setMaxResult(int maxResult):设定一次最多检索出的对象数目。

5、检索单个对象

Query和Criteria接口都提供了以下用以执行查询语句并返回查询结果的方法

list()方法:返回一个list类型的查询结果,在List集合中存放了所有满足查询条件的持久化对象。

uniqueResult()方法:返回单个对象

6、在HQL查询语句中绑定参数

session=HibernateUtil.getSession();
Query query=session.createQuery("from Customer as customer where customer.name='"+name+"'");
List customers=query.list();
return customers;

上面的代码尽管可以,但是不安全,Hibernate采用参数绑定机制来避免以上问题,Hibernate的参数绑定机制依赖于JDBC API中PreparedStatement的预定义Sql语句功能。参数绑定有以下优点:

①、非常安全。

②、能够利用底层数据库预编译SQL语句的功能,提供查询数据的性能。预编译是指在底层数据库系统只需要编译SQL语句一次,把编译出来的可执行代码保存在缓存中,如果多次执行相同形式的SQL语句,不需要重新编译,只要从缓存中获得可执行代码即可。

参数绑定的形式有两种:

<1>、按参数名字绑定

在HQL查询语句中定义命名参数,命名参数以“:”开头,形式如下:

Query query=session.createQuery("from Customer customer where customer.name=:name and customer.age=:age");

以上的HQL语句中定义了两个参数:name,age。下面接下里调用Query的setXXX()方法绑定参数。

query.setString("name",name);

<2>、按参数位置绑定

在HQL中使用“?”来定义参数的位置,则HQL为

Query query=session.createQuery("from Customer customer where customer.name=? and customer.age=?");

query.setString(0,name);

query.setInteger(1,age);

7、在映射文件中定义命名查询语句

Hibernate允许再映射文件中定义字符串形式的查询语句。在程序中通过Session的getNamedQuery()方法获取该查询语句。

8、设定查询条件

HQL查询语句也通过where字句来设定查询条件,值得注意是,在where字句中给出的是对象的属性名,而不是字段名。对于QBC查询,必须创建一个Criterion对象来设定查询条件。

HQL和QBC支持的各种运算

HQl运算符QBC运算符含义
=Expression.eq()等于
<>Expression.not(Expression.eq())不等于
>Expression.gt()大于
>=Expression.ge()大于等于
<Expression.lt()小于
<=Expression.le()小于等于
is nullExpression.isNull()等于空值
is not nullExpression.isNotNull()非空值
inExpression.in()等于列表中的某一值
not inExpression.not(Expression.in())
between 值1 and 值2Expression.between()
not between 值1 and 值2Expression.not(Expression.between())
likeExpression.like()
andExpression.and()或者Expression.conjunction()
orExpressioin.or()
notExpression.not()
9、连接查询

HQL与QBC也支持各种各样的链接查询,如内连接、外连接和交叉连接,迫切内连接、迫切外连接。

查询类型HQL语法QBC语法
内连接inner join或 joinCriteria.createAlias()
迫切内连接inner join fetch 或join fetch不支持
隐式内连接不支持
左外连接left outer join或者left join不支持
迫切左外连接left outer join fetch 或者 left join fetchFetchMode.EAGER
右外连接right outer join不支持
交叉连接ClassA,ClassB不支持
三、高级查询-------动态查询

1、HQL与QBC能够完成许多相同的任务,相比之下,HQL能更加直观的表达复杂的查询语句,而通过QBC表达复杂的查询语句很麻烦。因此如果,在程序运行前就明确了查询语句的内容(也成为静态查询),应该优先考虑HQL查询方式。但是如果只有在程序运行时才能明确查询 语句的内容(也称为动态查询),QBC比HQL更加方便。

在实际应用中,经常有这样的查询需求:用户在客户界面的查询窗口输入查询条件,按下查询按钮后,业务层执行查询操作,返回匹配的查询结果。

通过HQL来生成动态查询语句:

public List findCustomers(String username,String password){
session=HibernateUtil.getSession();
StringBuffer hqlStr=new StringBuffer("from SysUser as user");
if(username!=null)
hqlStr.append(" where user.username like :username");
if(password!=null && username!=null)
hqlStr.append(" and user.password=:password");
if(password!=null && username==null)
hqlStr.append(" where customer.password=:password");
Query query=session.createQuery(hqlStr.toString());
if(username!=null)
query.setString("username", username);
if(password!=null)
query.setString("password", password);
List list=query.list();
System.out.println(list.size());
return list;
}

如果采用QBC检索方式,可以简化编程:

public List findCustomers2(String username,String password){
session=HibernateUtil.getSession();
Criteria cri=session.createCriteria(SysUser.class);
if(username!=null)
cri.add(Expression.like("username", username,MatchMode.ANYWHERE));
if(password !=null)
cri.add(Expression.eq("password", password));
List list=cri.list();
System.out.println(list.size());
return list;
}

也可以使用QBE检索方式:

public List findCustomers3(Customer customer){
session=HibernateUtil.getSession();
Example exampleCustomer=Example.create(customer);
exampleCustomer.ignoreCase().enableLike(MatchMode.ANYWHERE);
exampleCustomer.excludeZeroes();
Criteria cri=session.createCriteria(SysUser.class).add(exampleCustomer);
return cri.list();
}

2、集合过滤

Session的createFilter()方法用来过滤集合。

四、本地SQL查询

HIbernate对本地SQL查询提供了内置的支持,为了把SQL查询返回的关系数据映射为对象,需要在SQL查询语句中为字段指定别名,Session的createSQLQuery()方法。

五、查询性能优化

Hibernate主要从以下几个方面来优化查询性能:

1、降低访问数据库的频率,减少select语句的数目。实现手段:

①、使用迫切左外连接或迫切内连接检索策略。

②、对延迟检索或立即检索设置批量检索数目。

③、使用查询缓存。

2、避免多余加载程序不需要访问的数据,实现手段:

①、使用延迟检索策略。

②、使用集合过滤。

3、避免报表查询数据占用缓存。实现手段为利用投影查询,查询出实体的部分属性。

4、减少select语句中的字段,从而降低访问数据库的数据量。实现手段:利用Query的iterate()方法。

六、iterate()方法

Query接口的iterate()方法和list()方法都能执行SQL查询语句,但是前者在有些情况下能轻微 提高查询性能。例如,以下程序代码两次检索Customer对象。

Query query1=session.CreateQuery("from Customer c");

List result1=query1.list();

Query query2=session.CreateQuery("from Customer c where c.age<30");

List result2=query2.list();

当第二次从数据库检索Customer对象时,Hibernate执行的SQL查询语句为select id,name ,age from customers where age <30

由于和以上查询结果对应的Customer对象已经存在于Session的缓存中,因此在这种情况下,Hibernate不需要重新创建Customer对象,只需要根据查询结果中的ID字段值返回缓存中匹配的Customer对象。可见,当第二次从数据库中检索Customer对象时,在select语句中其实只需要包含customer表的ID字段就可以了。

Query接口的iterate()方法首先检索ID字段,然后根据ID字段到Hibernate的第一级缓存以及第二级缓存中查找匹配的Customer对象,如果存在,就直接把它加入到查询结果集中,否则就执行额外的select语句,根据ID字段到数据库中检索该对象。

七、查询缓存

对于经常使用的查询语句,如果启用了查询缓存,当第一次执行查询语句时,Hibernate会把查询结果存放在第二级缓存中。以后再次执行该查询语句时,只需从缓存中获得查询结果,从而提供查询性能。如果查询结果中包含实体,第二级缓存只会存放实体的OID,而对于投影查询,第二级缓存会存放所有的数据值。

后面我们会详细介绍缓存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: