AP计算机科学A(APcomputer science A)复习备考攻略视频教程
43772 人在学
hibernate是一个开放源代码的对象关系映射(ORM)框架,是对java中的对象关系映射解决方案。而HQL是一种面向对象的查询语言,其中只有类、对象以及属性的概念。下面我们来看看HQL中查询函数以及在Java中应该如何使用。
HQL
在HIbernate中SQL是数据库的查询,和SQL不同的HQL则是面向对象查询。虽然两者的语法有点相似,但是查询的对象却不同。HIbernate是面向对象查询,它就像一个面向对象的SQL,所以它包含了许多面向对象语言的特性,这其中就包括了多态性、继承性以及组合。在功能上,HQL提供了更为强大的功能并且提供了很多的函数。下面我们来看一下这些函数:
投影函数
所谓投影就是一个可以访问的对象或者是可以访问的对象属性。在HQL中可以使用from和select子句来完成投影。
from
这是最简单的子句,它可以返回制定类中的所有实例。比如 from Name就会返回Name中所有的实例。实现如下:
SQL:select * from Order HQL:from Order
你也可以一次返回多个类中的实例
from Product,Order
和类名一样,别名也可以在from后面使用:
from Order as O,Product p
我们再看一些复杂的查询语句:下面的查询是一对多的关系。在HQL中相当于一个类中包含多个其它类的实例。
SQL:select o.*, N.* from order o, Name N where o.order_id = N.order_id
HQL:from Order as o inner join o.Products as Product
select
我们经常用select子句从一个表中得到指定的属性。使用如下:
SQL:select o.*, p.* from order o, product p where o.order_id = p.order_id
HQL使用select:select product from Order as o inner join o.products as product
这样会返回Order中product的所有实例。但是如果你只是要得到对象的某一个属性你就要这样写:
select product.name from Order as o inner join o.products as product
如果要的到多个对象的属性就要这样:
select o.id, product.name from Order as o inner join o.products as product
约束
我们可以根据上面的语句进行返回特定的属性,但是如果我们根据条件去查找数据,我们就要对数据进行过滤。在HQL中过滤数据的子句和SQL的一样,也是where。
语句如下:
SQL:select * from orders where id = ‘1234’
HQL:select o from Order o where o.id=’1234’
我们可以从两条语句中看出,两种语句非常相似,但是唯一的不同是SQL操作的是记录,HQL操作的是对象。在HQL中除了where还有having也可以做到这一点。
聚合函数
在约束和投影中的查询都是将每一个记录当做一个对象。而使用的聚合的话,就可以将一类对象当做一个单位。然后你就可以对这每一类的对象进行一系列的操作。
HQL中支持的聚合函数:
1. avg(…), sum(…)
2. min(…), max(…)
3. count(*), count(…), count(distinct…), count(all…)
在以上的聚合函数都返回数值类型。这些操作都可以在select子句中使用,语句如下:
select max(o.priceTotal) + max(p.price) from Order o join o.products p group by o.id
在这个HQL语句中返回了两个值的和:orders表中的priceTotal的最大值和products表中的price的最大值之和。
我们也可以使用下面的having语句事项按ID统计priceTotal小于1000的数量:
select count(o) from Order o having o.priceTotal < 1000 group by o.id
如果你要按products表的id统计price小于amount的平均数的产品数量,还可以将聚合函数与having子句一起使用,语句如下:
select count(p) from Product p having p.price < avg(amount) group by p.id
分组
分组操作是行的集合,函数会根据某一列的属性对记录集进行分组。HQL中的分组和SQL中的分组是相类似的。group是实现分组的关键,语句使用如下:
select count(o) from Order o having o.priceTotal >= 1200 and o.priceTotal <= 3200 group by o.id
也就是把查询出来的数据进行分组。
如何在Java中使用HQL
上面我们写了关于HQL中的基本用法。下面我们看看Java中HQL的使用。
首先使用HQL必须要引用的包
import java.util.List; import org.hibernate.*; import org.hibernate.cfg.* import com.Order; |
然后是关于类的声明
public class MyOrder |
实现MyOrder类的构造函数
public class MyOrder { SessionFactory sf; public MyOrder() { Configuration cfg = new Configuration().addClass(Order.class); sf = cfg.buildSessionFactory(); } … … } //getOrder函数根据priceTotal的区间值返回Order对象。 public class MyOrder { …. …. public Order getOrder(String lower, String upper) { // 打开一个会话 Session sess = sf.openSession(); // HQL语句 String query = "select o from o " + "Order as o join o.products as p " + "where o.priceTotal > :priceTotalLower" + "and o.priceTotal< :priceTotalUpper"; Query q = sess.createQuery(query); // 将两个参数传入HQL中 q.setDouble("priceTotalLower", Double.parseDouble(lower)); q.setDouble("priceTotalUpper", Double.parseDouble(upper)); List list = q.list(); Order o=(Order)list.iterator.next(); return o; } … … } |
最后使用鲸MyOrder类放入main函数进行测试。
public class MyOrder { … … public static void main(String args[]) { Order o=MyOrder().getOrder(“100”, “300”); System.out.println(“id=”+ o.id); … … } } |
如果没有使用过java实践HQL的朋友,在使用的时候还要注意一下的两点:
1.HQL并不区别大小写,但是HQL中的java类名和属性名必须要和实际的类名和属性名一致。例如在使用中SELECT和select意义相同,但是Order和order的两者的意义完全不同。
2.如果com.Order未被导入,在HQL中必须将Order写成com.Order。也就是说引用得类没有被导入,在使用中必须引入相应的包。
在HQL和SQL的比较之中,我们可以看出除了一些对SQL的特殊扩展外,其它所有的SQL功能都可以使用HQL描述。而且HQL面向对象的查询会比SQL的方便一点,所以HQL的学习还有平时的应用还有很重要的。