java hql_HIbernate中HQL的基础函数以及实现

hibernate是一个开放源代码的对象关系映射(ORM)框架,是对java中的对象关系映射解决方案。而HQL是一种面向对象的查询语言,其中只有类、对象以及属性的概念。下面我们来看看HQL中查询函数以及在Java中应该如何使用。

HQL

a48bdb47d895dd36173ef2898e23448c.png

在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。

bd42f452364d7bd60c8e9f5de2b71bc4.png

语句如下:

SQL:select * from orders where id = ‘1234’

HQL:select o from Order o where o.id=’1234’

我们可以从两条语句中看出,两种语句非常相似,但是唯一的不同是SQL操作的是记录,HQL操作的是对象。在HQL中除了where还有having也可以做到这一点。

聚合函数

在约束和投影中的查询都是将每一个记录当做一个对象。而使用的聚合的话,就可以将一类对象当做一个单位。然后你就可以对这每一类的对象进行一系列的操作。

19ecec352015301d5cde64389a2ec129.png

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

分组

6f74d13e7fcfd902181310f74e135da8.png

分组操作是行的集合,函数会根据某一列的属性对记录集进行分组。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的学习还有平时的应用还有很重要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值