- 浏览: 209658 次
- 来自: 深圳
文章分类
- 全部博客 (161)
- java (15)
- JSTL (3)
- 分页 (4)
- JDK (1)
- 正则表达式 (1)
- struts (2)
- JS (11)
- Tomcat (7)
- XML (1)
- JSP (7)
- MD5加密 (1)
- log4j (1)
- SVN (11)
- Jquery (2)
- myeclipse (3)
- 聚生网管2011 (1)
- 验证码 (2)
- Hibernate (2)
- Andriod (1)
- 网站测试 (2)
- ajax (1)
- linux (2)
- Spring (4)
- oracle (1)
- 个人所得 (4)
- Html (1)
- CSS (1)
- mysql (15)
- 省市区(县)联动 (2)
- 网页背景音乐 (3)
- FTP服务器搭建 (1)
- FTP (3)
- 404 500错误 (2)
- 网站域名绑定 (1)
- 遇到比较纠结的问题 (1)
- 记住密码 (1)
- QQ在线交谈功能 (1)
- Mail (1)
- java邮件 (1)
- java高并发 (1)
- 注册码 (0)
- HTTP状态码 (1)
- PHP (11)
- DZ论坛 (9)
- dz (1)
- ISAPI_Rewrite3 (1)
- asp (3)
- SEO (1)
- dedecms (2)
最新评论
-
shaode2012:
一个个网上都是宁愿写那么多的代码,文字,也没见到几个愿意用数据 ...
省市区(县)联动代码 -
lqfACCP:
...
Pager标签库(分页显示)详解
Hibernate Query Language(HQL)提供了十分强大的功能,推荐大家使用这种查询方式。HQL具有与SQL语言类似的语法规范,只不过SQL针对表中字段进行查询,而HQL针对持久化对象,它用来取得对象,而不进行update、delete和insert等操作。而且HQL是完全面向对象的,具备继承、多态和关联等特性。
1.from子句
from字句是最简单的HQL语句,例如 from Student,也可以写成select s from Student s。它简单地返回Student类的所有实例。
除了Java类和属性的名称外,HQL语句对大小写并不敏感,所以在上一句HQL语句中,from与FROM是相同的,但是Student 与student就不同了,所以上述语句写成from student就会报错。下列程序演示如何通过执行from语句取得所有的Student对象。
Query query = session.createQuery(“from Student”);
List list = query.list();
for (int i=0;i<list.size(); i++)
{
Student stu = (Student)list.get(i);
System.out.println(stu.getName());
}
如果执行HQL语句“from Student, Course”,并不简单地返回两个对象,而是返回这两个对象的的笛卡儿积,这类似于SQL语句中字段的全外连接。在实际应用中,像“from Student, Course”这样的语句几乎不会出现。
2.select子句
有时并不需要得到对象的所有属性,这时可以使用select子句进行属性查询,例如,select s.name from Student s。下面程序演示如何执行这个语句:
Query query = session.createQuery(“select s.name from Student s”);
List list = query.list();
for (int i=0;i<list.size(); i++) {
String name = (String)list.get(i);
System.out.println(ame());
}
如果要查询两个以上的属性,查询结果会以数组的方式返回,如下所示:
Query query = session.createQuery(“select s.name, s.sex from Student as s”);
List list = query.list();
for (int i=0;i<list.size(); i++) {
Object obj[] = (Object[])list.get(i);
System.out.println(ame(obj[0] + “的性别是:” +obj[1]));
}
在使用属性查询时,由于使用对象数组,操作和理解都不太方便,如果将一个object[]中所有成员封装成一个对象就方便多了。下面的程序将查询结果进行了实例化:
Query query = session.createQuery(“select new Student(s.name, s.sex) from Student s”);
List list = query.list();
for (int i=0;i<list.size(); i++) {
Student stu = (Student)list.get(i);
System.out.println(stu.getName());
}
要正确运行以上程序,还需要在Student类中加入一个如下的构造函数:
public Student(String name, String sex)
{
this.name = name;
this.sex = sex;
}
3.统计函数查询
可以在HQL中使用函数,经常使用的函数有:
count():统计记录条数
min():求最小值
max():求最大值
sum():求和
age():求平均值
例如,要取得Student实例的数量,可以编写如下HQL语句:
select count(*) from Student
取得Student的平均年龄的HQL语句如下:
select avg(s.age) from Student as s
可以使用distinct去除重复数据:
select distinct s.age from Student as s
4.where子句
HQL也支持子查询,它通过where子句实现这一机制。where子句让用户缩小要返回的实例的列表范围,例如下面语句会返回所有名字为“Bill”的Student实例:
Query query = session.createQuery("from Student as s where s.name='Bill' ");
where子句允许出现的表达式包括了SQL中可以使用的大多数情况:
数学操作:+,-,*,/
真假比较操作:=,>=,<=,<>,!=,like
逻辑操作:and,or, not
字符串连接:||
SQL标量函数:例如upper()和lower()
如果子查询返回多条记录,可以用以下的关键字来量化:
all:表示所有的记录。
any:表示所有记录中的任意一条。
some:与any用法相同。
in:与any等价。
exists:表示子查询至少要返回一条记录。
例如,下面语句返回所有学生的年龄都大于22的班级对象:
from Group g where 22<all (select s.age from g.students s)
下述语句返回在所有学生中有一个学生的年龄等于22的班级:
from Group g where 22=any (select s.age from g.students s)
或者
from Group g where 22=some (select s.age from g.students s)
或者
from Group g where 22 in (select s.age from g.students s)
5.order by 子句
查询返回的列表可以按照任何返回的类或者组件的属性排序:
from Student s order by s.name asc
asc和desc是可选的,分别代表升序或者降序。
6.连接查询
与SQL查询一样, HQL也支持连接查询,如内连接、外连接和交叉连接。
inner join: 内连接
left outer join:左外连接
right outer join:右外连接
full join: 全连接,但不常用
下面重点讲解内连接查询,左外连接和右外连接查询和内连接大同小异,而全连接几乎不怎么使用。
inner join可以简写为join,例如在查询得到Group对象时,内连接取得对应的Student对象,实现的程序如下。
……//打开Session,开启事务
Student stu = null; //声明Student实例
Group group = null; //声明Group实例
Query query = session.createQuery("from Group g join g.students");
List list = query.list();
Object obj[] = null; //声明对象数组
for(int i=0;i<list.size();i++) {
obj = (Object[])list.get(i); //取得集合中的第i个数组
group = (Group)obj[0]; //group是数组中第一个对象
stu = (Student)obj[1]; //stu是数组中第二个对象
System.out.println(stu.getName() + "属于:" +group.getName() );
}
……//提交事务,关闭Session
上面提到以下,下面是详细带例子和大家共同学习!
Hibernate装备了一种极为有力的查询语言,(有意地)看上去很像SQL。但是别被语法蒙蔽,HQL是完全面向对象的,具备继承、多态和关联等特性。
10.1. 大小写敏感性(Case Sensitivity)
除了Java类和属性名称外,查询都是大小写不敏感的。 所以, SeLeCT 和 sELEct 以及 SELECT 相同的,但是 net.sf.hibernate.eg.FOO 和 net.sf.hibernate.eg.Foo 是不同的, foo.barSet 和 foo.BARSET也是不同的。
本手册使用小写的HQL关键词。有些用户认为在查询中使用大写的关键字更加易读,但是我们认为嵌入在Java代码中这样很难看。
10.2. from 子句
可能最简单的Hibernate查询是这样的形式:
from eg.Cat
它简单的返回所有eg.Cat类的实例。
大部分情况下,你需要赋予它一个别名(alias),因为你在查询的其他地方也会引用这个Cat。
from eg.Cat as cat
上面的语句为Cat赋予了一个别名cat 。所以后面的查询可以用这个简单的别名了。as关键字是可以省略的,我们也可以写成这样:
from eg.Cat cat
可以出现多个类,结果是它们的笛卡尔积,或者称为“交叉”连接。
from Formula, Parameterfrom Formula as form, Parameter as param
让查询中的别名服从首字母小写的规则,我们认为这是一个好习惯。这和Java对局部变量的命名规范是一致的。(比如,domesticCat).
10.3. 联合(Associations)和连接(joins)
你可以使用join定义两个实体的连接,同时指明别名。
from eg.Cat as cat
inner join cat.mate as mate
left outer join cat.kittens as kitten
from eg.Cat as cat left join cat.mate.kittens as kittens
from Formula form full join form.parameter param
支持的连接类型是从ANSI SQL借用的:
内连接,inner join
左外连接,left outer join
右外连接,right outer join
全连接,full join (不常使用)
inner join, left outer join 和 right outer join 都可以简写。
from eg.Cat as cat
join cat.mate as mate
left join cat.kittens as kitten
并且,加上 "fetch"后缀的抓取连接可以让联合的对象随着它们的父对象的初始化而初始化,只需要一个select语句。这在初始化一个集合的时候特别有用。
from eg.Cat as cat
inner join fetch cat.mate
left join fetch cat.kittens
抓取连接一般不需要赋予别名,因为被联合的对象应该不会在where子句(或者任何其它子句)中出现。并且,被联合的对象也不会在查询结果中直接出现。它们是通过父对象进行访问的。
请注意,目前的实现中,在一次查询中只会抓取一个集合(?原文为:only one collection role may be fetched in a query)。也请注意,在使用scroll()或者 iterate()方式调用的查询中,是禁止使用fetch构造的。最后,请注意full join fetch和right join fetch是没有意义的。
10.4. select子句
select子句选择在结果集中返回哪些对象和属性。思考一下下面的例子:
select mate
from eg.Cat as cat
inner join cat.mate as mate
这个查询会选择出作为其它猫(Cat)朋友(mate)的那些猫。当然,你可以更加直接的写成下面的形式:
select cat.mate from eg.Cat cat
你甚至可以选择集合元素,使用特殊的elements功能。下面的查询返回所有猫的小猫。
select elements(cat.kittens) from eg.Cat cat
查询可以返回任何值类型的属性,包括组件类型的属性:
select cat.name from eg.DomesticCat cat
where cat.name like 'fri%'
select cust.name.firstName from Customer as cust
查询可以用元素类型是Object[]的一个数组返回多个对象和/或多个属性。
select mother, offspr, mate.name
from eg.DomesticCat as mother
inner join mother.mate as mate
left outer join mother.kittens as offspr
或者实际上是类型安全的Java对象
select new Family(mother, mate, offspr)
from eg.DomesticCat as mother
join mother.mate as mate
left join mother.kittens as offspr
上面的代码假定Family有一个合适的构造函数。
10.5. 统计函数(Aggregate functions)
查询可以返回属性的统计函数。
select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)
from eg.Cat cat
在select子句中,统计函数的变量也可以是集合。
select cat, count( elements(cat.kittens) )
from eg.Cat cat group by cat
下面是支持的统计函数列表:
avg(...), sum(...), min(...), max(...)
count(*)
count(...), count(distinct ...), count(all...)
distinct 和 all关键字的用法和语义与SQL相同。
select distinct cat.name from eg.Cat cat
select count(distinct cat.name), count(cat) from eg.Cat cat
10.6. 多态(polymorphism)
类似下面的查询:
from eg.Cat as cat
返回的实例不仅仅是Cat,也有可能是子类的实例,比如DomesticCat。Hibernate查询可以在from子句中使用任何Java类或者接口的名字。查询可能返回所有继承自这个类或者实现这个接口的持久化类的实例。下列查询会返回所有的持久化对象:
from java.lang.Object o
可能有多个持久化类都实现了Named接口:
from eg.Named n, eg.Named m where n.name = m.name
请注意,上面两个查询都使用了超过一个SQL的SELECT。这意味着order by子句将不会正确排序。(这也意味着你不能对这些查询使用Query.scroll()。)
10.7. where子句
where子句让你缩小你要返回的实例的列表范围。
from eg.Cat as cat where cat.name='Fritz'
返回所有名字为'Fritz'的Cat的实例。
select foo
from eg.Foo foo, eg.Bar bar
where foo.startDate = bar.date
会返回所有的满足下列条件的Foo实例,它们存在一个对应的bar实例,其date属性与Foo的startDate属性相等。复合路径表达式令where子句变得极为有力。思考下面的例子:
from eg.Cat cat where cat.mate.name is not null
这个查询会被翻译为带有一个表间(inner)join的SQL查询。如果你写下类似这样的语句:
from eg.Foo foo
where foo.bar.baz.customer.address.city is not null
你最终会得到的查询,其对应的SQL需要4个表间连接。
=操作符不仅仅用于判断属性是否相等,也可以用于实例:
from eg.Cat cat, eg.Cat rival where cat.mate = rival.mate
select cat, mate
from eg.Cat cat, eg.Cat mate
where cat.mate = mate
特别的,小写的id可以用来表示一个对象的惟一标识。(你可以使用它的属性名。)
from eg.Cat as cat where cat.id = 123
from eg.Cat as cat where cat.mate.id = 69
第二个查询是很高效的。不需要进行表间连接!
组合的标示符也可以使用。假设Person有一个组合标示符,是由country和medicareNumber组合而成的。
from bank.Person person
where person.id.country = 'AU'
and person.id.medicareNumber = 123456
from bank.Account account
where account.owner.id.country = 'AU'
and account.owner.id.medicareNumber = 123456
又一次,第二个查询不需要表间连接。
类似的,在存在多态持久化的情况下,特殊属性class用于获取某个实例的辨识值。在where子句中嵌入的Java类名将会转换为它的辨识值。
from eg.Cat cat where cat.class = eg.DomesticCat
你也可以指定组件(或者是组件的组件,依次类推)或者组合类型中的属性。但是在一个存在路径的表达式中,最后不能以一个组件类型的属性结尾。(这里不是指组件的属性)。比如,假若store.owner这个实体的的address是一个组件
store.owner.address.city //okay
store.owner.address //error!
“任意(any)”类型也有特殊的id属性和class属性,这可以让我们用下面的形式来表达连接(这里AuditLog.item是一个对应到<ant>的属性)。
from eg.AuditLog log, eg.Payment payment
where log.item.class = 'eg.Payment' and log.item.id = payment.id
注意上面查询中,log.item.class和payment.class会指向两个值,代表完全不同的数据库字段。
10.8. 表达式(Expressions)
where子句允许出现的表达式包括了你在SQL中可以使用的大多数情况:
数学操作+, -, *, /
真假比较操作 =, >=, <=, <>, !=, like
逻辑操作 and, or, not
字符串连接 ||
SQL标量( scalar)函数,例如 upper() 和 lower()
没有前缀的 ( )表示分组
in, between, is null
JDBC 传入参数?
命名参数 :name, :start_date,1
SQL 文字 'foo', 69, '1970-01-01 10:00:01.0'
Java的public static final常量比如 Color.TABBY
in 和 between 可以如下例一样使用:
from eg.DomesticCat cat where cat.name between 'A' and 'B'
from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )
其否定形式为
from eg.DomesticCat cat where cat.name not between 'A' and 'B'
from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )
类似的,is null和is not null可以用来测试null值。
通过在Hibernate配置中声明HQL查询的替换方式,Boolean也是很容易在表达式中使用的:
<property name="hibernate.query.substitutions">true 1, false 0</property>
在从HQL翻译成SQL的时候,关键字true和false就会被替换成1和0。
from eg.Cat cat where cat.alive = true
你可以用特殊属性size来测试一个集合的长度,或者用特殊的size()函数也可以。
from eg.Cat cat where cat.kittens.size > 0
from eg.Cat cat where size(cat.kittens) > 0
对于排序集合,你可以用minIndex和maxIndex来获取其最大索引值和最小索引值。类似的,minElement 和maxElement 可以用来获取集合中最小和最大的元素,前提是必须是基本类型的集合。
from Calendar cal where cal.holidays.maxElement > current date
也有函数的形式(和上面的形式不同,函数形式是大小写不敏感的):
from Order order where maxindex(order.items) > 100
from Order order where minelement(order.items) > 10000
SQL中的any, some, all, exists, in功能也是支持的,前提是必须把集合的元素或者索引集作为它们的参数(使用element和indices函数),或者使用子查询的结果作为参数。
select mother from eg.Cat as mother, eg.Cat as kit
where kit in elements(foo.kittens)
select p from eg.NameList list, eg.Person p
where p.name = some elements(list.names)
from eg.Cat cat where exists elements(cat.kittens)
from eg.Player p where 3 > all elements(p.scores)
from eg.Show show where 'fizard' in indices(show.acts)
请注意这些设施:size,elements,indices,minIndex,maxIndex,minElement,maxElement 都有一些使用限制:
在where子句中: 只对支持子查询的数据库有效
在select子句中:只有elements和indices有效
有序的集合(数组、list、map)的元素可以用索引来进行引用(只限于在where子句中)
from Order order where order.items[0].id = 1234
select person from Person person, Calendar calendar
where calendar.holidays['national day'] = person.birthDay
and person.nationality.calendar = calendar
select item from Item item, Order order
where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11
select item from Item item, Order order
where order.items[ maxindex(order.items) ] = item and order.id = 11
[]中的表达式允许是另一个数学表达式。
select item from Item item, Order order
where order.items[ size(order.items) - 1 ] = item
HQL也对一对多关联或者值集合提供内置的index()函数。
select item, index(item) from Order order
join order.items item
where index(item) < 5
底层数据库支持的标量SQL函数也可以使用
from eg.DomesticCat cat where upper(cat.name) like 'FRI%'
假如以上的这些还没有让你信服的话,请想象一下下面的查询假若用SQL来写,会变得多么长,多么不可读:
select cust
from Product prod,
Store store
inner join store.customers cust
where prod.name = 'widget'
and store.location.name in ( 'Melbourne', 'Sydney' )
and prod = all elements(cust.currentOrder.lineItems)
提示:对应的SQL语句可能是这样的
SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
FROM customers cust,
stores store,
locations loc,
store_customers sc,
product prod
WHERE prod.name = 'widget'
AND store.loc_id = loc.id
AND loc.name IN ( 'Melbourne', 'Sydney' )
AND sc.store_id = store.id
AND sc.cust_id = cust.id
AND prod.id = ALL(
SELECT item.prod_id
FROM line_items item, orders o
WHERE item.order_id = o.id
AND cust.current_order = o.id
)
10.9. order by 子句
查询返回的列表可以按照任何返回的类或者组件的属性排序:
from eg.DomesticCat cat
order by cat.name asc, cat.weight desc, cat.birthdate
asc和desc是可选的,分别代表升序或者降序。
10.10. group by 子句
返回统计值的查询可以按照返回的类或者组件的任何属性排序:
select cat.color, sum(cat.weight), count(cat)
from eg.Cat cat
group by cat.color
select foo.id, avg( elements(foo.names) ), max( indices(foo.names) )
from eg.Foo foo
group by foo.id
请注意:你可以在select子句中使用elements和indices指令,即使你的数据库不支持子查询也可以。
having子句也是允许的。
select cat.color, sum(cat.weight), count(cat)
from eg.Cat cat
group by cat.color
having cat.color in (eg.Color.TABBY, eg.Color.BLACK)
在having子句中允许出现SQL函数和统计函数,当然这需要底层数据库支持才行。(比如说,MySQL就不支持)
select cat
from eg.Cat cat
join cat.kittens kitten
group by cat
having avg(kitten.weight) > 100
order by count(kitten) asc, sum(kitten.weight) desc
注意,group by子句和order by子句都不支持数学表达式。
10.11. 子查询
对于支持子查询的数据库来说,Hibernate支持在查询中嵌套子查询。子查询必须由圆括号包围(常常是在一个SQL统计函数中)。也允许关联子查询(在外部查询中作为一个别名出现的子查询)。
from eg.Cat as fatcat
where fatcat.weight > (
select avg(cat.weight) from eg.DomesticCat cat
)
from eg.DomesticCat as cat
where cat.name = some (
select name.nickName from eg.Name as name
)
from eg.Cat as cat
where not exists (
from eg.Cat as mate where mate.mate = cat
)
from eg.DomesticCat as cat
where cat.name not in (
select name.nickName from eg.Name as name
)
10.12. 示例
Hibernate查询可以非常强大复杂。实际上,强有力的查询语言是Hibernate的主要卖点之一。下面给出的示例与我在近期实际项目中使用的一些查询很类似。请注意你编写的查询大部分等都不会这么复杂!
下面的查询对特定的客户,根据给定的最小总计值(minAmount),查询出所有未付订单,返回其订单号、货品总数、订单总金额,结果按照总金额排序。在决定价格的时候,参考当前目录。产生的SQL查询,在ORDER,ORDER_LINE,PRODUCT,CATALOG和PRICE表之间有四个内部连接和一个没有产生关联的字查询。
select order.id, sum(price.amount), count(item)
from Order as order
join order.lineItems as item
join item.product as product,
Catalog as catalog
join catalog.prices as price
where order.paid = false
and order.customer = :customer
and price.product = product
and catalog.effectiveDate < sysdate
and catalog.effectiveDate >= all (
select cat.effectiveDate
from Catalog as cat
where cat.effectiveDate < sysdate
)
group by order
having sum(price.amount) > :minAmount
order by sum(price.amount) desc
好家伙,真长!实际上,在现实生活中我并不是非常热衷于子查询,所以我的查询往往是这样的:
select order.id, sum(price.amount), count(item)
from Order as order
join order.lineItems as item
join item.product as product,
Catalog as catalog
join catalog.prices as price
where order.paid = false
and order.customer = :customer
and price.product = product
and catalog = :currentCatalog
group by order
having sum(price.amount) > :minAmount
order by sum(price.amount) desc
下面的查询统计付款记录处于每种状态中的数量,要排除所有处于AWAITING_APPROVAL状态的,或者最近一次状态更改是由当前用户做出的。它翻译成SQL查询后,在PAYMENT,PAYMENT_STATUS和PAYMENT_STATUS_CHANGE表之间包含两个内部连接和一个用于关联的子查询。
select count(payment), status.name
from Payment as payment
join payment.currentStatus as status
join payment.statusChanges as statusChange
where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
or (
statusChange.timeStamp = (
select max(change.timeStamp)
from PaymentStatusChange change
where change.payment = payment
)
and statusChange.user <> :currentUser
)
group by status.name, status.sortOrder
order by status.sortOrder
假若我已经把statusChange集合映射为一个列表而不是一个集合的话,查询写起来会简单很多。
select count(payment), status.name
from Payment as payment
join payment.currentStatus as status
where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser
group by status.name, status.sortOrder
order by status.sortOrder
下面的查询使用了MS SQL Server的isNull()函数,返回当前用户所属的组织所有账户和未付支出。翻译为SQL查询后,在ACCOUNT, PAYMENT, PAYMENT_STATUS,ACCOUNT_TYPE, ORGANIZATION 和 ORG_USER表之间有三个内部连接,一个外部连接和一个子查询。
select account, payment
from Account as account
left outer join account.payments as payment
where :currentUser in elements(account.holder.users)
and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
order by account.type.sortOrder, account.accountNumber, payment.dueDate
对某些数据库而言,我们可能不能依赖(关联的)子查询。
select account, payment
from Account as account
join account.holder.users as user
left outer join account.payments as payment
where :currentUser = user
and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
order by account.type.sortOrder, account.accountNumber, payment.dueDate
10.13. 提示和技巧(Tips & Tricks)
你不返回结果集也可以查询结果集的大小:
( (Integer) session.iterate("select count(*) from ....").next() ).intValue()
要依据一个集合的大小对结果集排序,可以用下面的查询来对付一对多或多对多的关联:
select usr
from User as usr
left join usr.messages as msg
group by usr
order by count(msg)
如果你的数据库支持子查询,你可以在查询的where子句中对选择的大小进行条件限制:
from User usr where size(usr.messages) >= 1
如果你的数据库不支持子查询,可以使用下列查询:
select usr.id, usr.name
from User usr.name
join usr.messages msg
group by usr.id, usr.name
having count(msg) >= 1
因为使用了inner join,这个解决方法不能返回没有message的User.下面的方式就可以:
select usr
from User as usr
left join usr.messages as msg
group by usr
having count(msg) = 0
JavaBean的属性可以直接作为命名的查询参数:
Query q = s.createQuery("from foo in class Foo where foo.name=:name and foo.size=:size");
q.setProperties(fooBean); // fooBean has getName() and getSize()
List foos = q.list();
在Query接口中使用过滤器(filter),可以对集合分页:
Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();
集合元素可以使用查询过滤器(query filter)进行排序或者分组:
List orderedCollection = s.filter( collection, "order by this.amount" );
List counts = s.filter( collection, "select this.type, count(this) group by this.type" );
不用初始化集合就可以得到其大小:
( (Integer) session.iterate("select count(*) from ....").next() ).intValue();
1.from子句
from字句是最简单的HQL语句,例如 from Student,也可以写成select s from Student s。它简单地返回Student类的所有实例。
除了Java类和属性的名称外,HQL语句对大小写并不敏感,所以在上一句HQL语句中,from与FROM是相同的,但是Student 与student就不同了,所以上述语句写成from student就会报错。下列程序演示如何通过执行from语句取得所有的Student对象。
Query query = session.createQuery(“from Student”);
List list = query.list();
for (int i=0;i<list.size(); i++)
{
Student stu = (Student)list.get(i);
System.out.println(stu.getName());
}
如果执行HQL语句“from Student, Course”,并不简单地返回两个对象,而是返回这两个对象的的笛卡儿积,这类似于SQL语句中字段的全外连接。在实际应用中,像“from Student, Course”这样的语句几乎不会出现。
2.select子句
有时并不需要得到对象的所有属性,这时可以使用select子句进行属性查询,例如,select s.name from Student s。下面程序演示如何执行这个语句:
Query query = session.createQuery(“select s.name from Student s”);
List list = query.list();
for (int i=0;i<list.size(); i++) {
String name = (String)list.get(i);
System.out.println(ame());
}
如果要查询两个以上的属性,查询结果会以数组的方式返回,如下所示:
Query query = session.createQuery(“select s.name, s.sex from Student as s”);
List list = query.list();
for (int i=0;i<list.size(); i++) {
Object obj[] = (Object[])list.get(i);
System.out.println(ame(obj[0] + “的性别是:” +obj[1]));
}
在使用属性查询时,由于使用对象数组,操作和理解都不太方便,如果将一个object[]中所有成员封装成一个对象就方便多了。下面的程序将查询结果进行了实例化:
Query query = session.createQuery(“select new Student(s.name, s.sex) from Student s”);
List list = query.list();
for (int i=0;i<list.size(); i++) {
Student stu = (Student)list.get(i);
System.out.println(stu.getName());
}
要正确运行以上程序,还需要在Student类中加入一个如下的构造函数:
public Student(String name, String sex)
{
this.name = name;
this.sex = sex;
}
3.统计函数查询
可以在HQL中使用函数,经常使用的函数有:
count():统计记录条数
min():求最小值
max():求最大值
sum():求和
age():求平均值
例如,要取得Student实例的数量,可以编写如下HQL语句:
select count(*) from Student
取得Student的平均年龄的HQL语句如下:
select avg(s.age) from Student as s
可以使用distinct去除重复数据:
select distinct s.age from Student as s
4.where子句
HQL也支持子查询,它通过where子句实现这一机制。where子句让用户缩小要返回的实例的列表范围,例如下面语句会返回所有名字为“Bill”的Student实例:
Query query = session.createQuery("from Student as s where s.name='Bill' ");
where子句允许出现的表达式包括了SQL中可以使用的大多数情况:
数学操作:+,-,*,/
真假比较操作:=,>=,<=,<>,!=,like
逻辑操作:and,or, not
字符串连接:||
SQL标量函数:例如upper()和lower()
如果子查询返回多条记录,可以用以下的关键字来量化:
all:表示所有的记录。
any:表示所有记录中的任意一条。
some:与any用法相同。
in:与any等价。
exists:表示子查询至少要返回一条记录。
例如,下面语句返回所有学生的年龄都大于22的班级对象:
from Group g where 22<all (select s.age from g.students s)
下述语句返回在所有学生中有一个学生的年龄等于22的班级:
from Group g where 22=any (select s.age from g.students s)
或者
from Group g where 22=some (select s.age from g.students s)
或者
from Group g where 22 in (select s.age from g.students s)
5.order by 子句
查询返回的列表可以按照任何返回的类或者组件的属性排序:
from Student s order by s.name asc
asc和desc是可选的,分别代表升序或者降序。
6.连接查询
与SQL查询一样, HQL也支持连接查询,如内连接、外连接和交叉连接。
inner join: 内连接
left outer join:左外连接
right outer join:右外连接
full join: 全连接,但不常用
下面重点讲解内连接查询,左外连接和右外连接查询和内连接大同小异,而全连接几乎不怎么使用。
inner join可以简写为join,例如在查询得到Group对象时,内连接取得对应的Student对象,实现的程序如下。
……//打开Session,开启事务
Student stu = null; //声明Student实例
Group group = null; //声明Group实例
Query query = session.createQuery("from Group g join g.students");
List list = query.list();
Object obj[] = null; //声明对象数组
for(int i=0;i<list.size();i++) {
obj = (Object[])list.get(i); //取得集合中的第i个数组
group = (Group)obj[0]; //group是数组中第一个对象
stu = (Student)obj[1]; //stu是数组中第二个对象
System.out.println(stu.getName() + "属于:" +group.getName() );
}
……//提交事务,关闭Session
上面提到以下,下面是详细带例子和大家共同学习!
Hibernate装备了一种极为有力的查询语言,(有意地)看上去很像SQL。但是别被语法蒙蔽,HQL是完全面向对象的,具备继承、多态和关联等特性。
10.1. 大小写敏感性(Case Sensitivity)
除了Java类和属性名称外,查询都是大小写不敏感的。 所以, SeLeCT 和 sELEct 以及 SELECT 相同的,但是 net.sf.hibernate.eg.FOO 和 net.sf.hibernate.eg.Foo 是不同的, foo.barSet 和 foo.BARSET也是不同的。
本手册使用小写的HQL关键词。有些用户认为在查询中使用大写的关键字更加易读,但是我们认为嵌入在Java代码中这样很难看。
10.2. from 子句
可能最简单的Hibernate查询是这样的形式:
from eg.Cat
它简单的返回所有eg.Cat类的实例。
大部分情况下,你需要赋予它一个别名(alias),因为你在查询的其他地方也会引用这个Cat。
from eg.Cat as cat
上面的语句为Cat赋予了一个别名cat 。所以后面的查询可以用这个简单的别名了。as关键字是可以省略的,我们也可以写成这样:
from eg.Cat cat
可以出现多个类,结果是它们的笛卡尔积,或者称为“交叉”连接。
from Formula, Parameterfrom Formula as form, Parameter as param
让查询中的别名服从首字母小写的规则,我们认为这是一个好习惯。这和Java对局部变量的命名规范是一致的。(比如,domesticCat).
10.3. 联合(Associations)和连接(joins)
你可以使用join定义两个实体的连接,同时指明别名。
from eg.Cat as cat
inner join cat.mate as mate
left outer join cat.kittens as kitten
from eg.Cat as cat left join cat.mate.kittens as kittens
from Formula form full join form.parameter param
支持的连接类型是从ANSI SQL借用的:
内连接,inner join
左外连接,left outer join
右外连接,right outer join
全连接,full join (不常使用)
inner join, left outer join 和 right outer join 都可以简写。
from eg.Cat as cat
join cat.mate as mate
left join cat.kittens as kitten
并且,加上 "fetch"后缀的抓取连接可以让联合的对象随着它们的父对象的初始化而初始化,只需要一个select语句。这在初始化一个集合的时候特别有用。
from eg.Cat as cat
inner join fetch cat.mate
left join fetch cat.kittens
抓取连接一般不需要赋予别名,因为被联合的对象应该不会在where子句(或者任何其它子句)中出现。并且,被联合的对象也不会在查询结果中直接出现。它们是通过父对象进行访问的。
请注意,目前的实现中,在一次查询中只会抓取一个集合(?原文为:only one collection role may be fetched in a query)。也请注意,在使用scroll()或者 iterate()方式调用的查询中,是禁止使用fetch构造的。最后,请注意full join fetch和right join fetch是没有意义的。
10.4. select子句
select子句选择在结果集中返回哪些对象和属性。思考一下下面的例子:
select mate
from eg.Cat as cat
inner join cat.mate as mate
这个查询会选择出作为其它猫(Cat)朋友(mate)的那些猫。当然,你可以更加直接的写成下面的形式:
select cat.mate from eg.Cat cat
你甚至可以选择集合元素,使用特殊的elements功能。下面的查询返回所有猫的小猫。
select elements(cat.kittens) from eg.Cat cat
查询可以返回任何值类型的属性,包括组件类型的属性:
select cat.name from eg.DomesticCat cat
where cat.name like 'fri%'
select cust.name.firstName from Customer as cust
查询可以用元素类型是Object[]的一个数组返回多个对象和/或多个属性。
select mother, offspr, mate.name
from eg.DomesticCat as mother
inner join mother.mate as mate
left outer join mother.kittens as offspr
或者实际上是类型安全的Java对象
select new Family(mother, mate, offspr)
from eg.DomesticCat as mother
join mother.mate as mate
left join mother.kittens as offspr
上面的代码假定Family有一个合适的构造函数。
10.5. 统计函数(Aggregate functions)
查询可以返回属性的统计函数。
select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)
from eg.Cat cat
在select子句中,统计函数的变量也可以是集合。
select cat, count( elements(cat.kittens) )
from eg.Cat cat group by cat
下面是支持的统计函数列表:
avg(...), sum(...), min(...), max(...)
count(*)
count(...), count(distinct ...), count(all...)
distinct 和 all关键字的用法和语义与SQL相同。
select distinct cat.name from eg.Cat cat
select count(distinct cat.name), count(cat) from eg.Cat cat
10.6. 多态(polymorphism)
类似下面的查询:
from eg.Cat as cat
返回的实例不仅仅是Cat,也有可能是子类的实例,比如DomesticCat。Hibernate查询可以在from子句中使用任何Java类或者接口的名字。查询可能返回所有继承自这个类或者实现这个接口的持久化类的实例。下列查询会返回所有的持久化对象:
from java.lang.Object o
可能有多个持久化类都实现了Named接口:
from eg.Named n, eg.Named m where n.name = m.name
请注意,上面两个查询都使用了超过一个SQL的SELECT。这意味着order by子句将不会正确排序。(这也意味着你不能对这些查询使用Query.scroll()。)
10.7. where子句
where子句让你缩小你要返回的实例的列表范围。
from eg.Cat as cat where cat.name='Fritz'
返回所有名字为'Fritz'的Cat的实例。
select foo
from eg.Foo foo, eg.Bar bar
where foo.startDate = bar.date
会返回所有的满足下列条件的Foo实例,它们存在一个对应的bar实例,其date属性与Foo的startDate属性相等。复合路径表达式令where子句变得极为有力。思考下面的例子:
from eg.Cat cat where cat.mate.name is not null
这个查询会被翻译为带有一个表间(inner)join的SQL查询。如果你写下类似这样的语句:
from eg.Foo foo
where foo.bar.baz.customer.address.city is not null
你最终会得到的查询,其对应的SQL需要4个表间连接。
=操作符不仅仅用于判断属性是否相等,也可以用于实例:
from eg.Cat cat, eg.Cat rival where cat.mate = rival.mate
select cat, mate
from eg.Cat cat, eg.Cat mate
where cat.mate = mate
特别的,小写的id可以用来表示一个对象的惟一标识。(你可以使用它的属性名。)
from eg.Cat as cat where cat.id = 123
from eg.Cat as cat where cat.mate.id = 69
第二个查询是很高效的。不需要进行表间连接!
组合的标示符也可以使用。假设Person有一个组合标示符,是由country和medicareNumber组合而成的。
from bank.Person person
where person.id.country = 'AU'
and person.id.medicareNumber = 123456
from bank.Account account
where account.owner.id.country = 'AU'
and account.owner.id.medicareNumber = 123456
又一次,第二个查询不需要表间连接。
类似的,在存在多态持久化的情况下,特殊属性class用于获取某个实例的辨识值。在where子句中嵌入的Java类名将会转换为它的辨识值。
from eg.Cat cat where cat.class = eg.DomesticCat
你也可以指定组件(或者是组件的组件,依次类推)或者组合类型中的属性。但是在一个存在路径的表达式中,最后不能以一个组件类型的属性结尾。(这里不是指组件的属性)。比如,假若store.owner这个实体的的address是一个组件
store.owner.address.city //okay
store.owner.address //error!
“任意(any)”类型也有特殊的id属性和class属性,这可以让我们用下面的形式来表达连接(这里AuditLog.item是一个对应到<ant>的属性)。
from eg.AuditLog log, eg.Payment payment
where log.item.class = 'eg.Payment' and log.item.id = payment.id
注意上面查询中,log.item.class和payment.class会指向两个值,代表完全不同的数据库字段。
10.8. 表达式(Expressions)
where子句允许出现的表达式包括了你在SQL中可以使用的大多数情况:
数学操作+, -, *, /
真假比较操作 =, >=, <=, <>, !=, like
逻辑操作 and, or, not
字符串连接 ||
SQL标量( scalar)函数,例如 upper() 和 lower()
没有前缀的 ( )表示分组
in, between, is null
JDBC 传入参数?
命名参数 :name, :start_date,1
SQL 文字 'foo', 69, '1970-01-01 10:00:01.0'
Java的public static final常量比如 Color.TABBY
in 和 between 可以如下例一样使用:
from eg.DomesticCat cat where cat.name between 'A' and 'B'
from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )
其否定形式为
from eg.DomesticCat cat where cat.name not between 'A' and 'B'
from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )
类似的,is null和is not null可以用来测试null值。
通过在Hibernate配置中声明HQL查询的替换方式,Boolean也是很容易在表达式中使用的:
<property name="hibernate.query.substitutions">true 1, false 0</property>
在从HQL翻译成SQL的时候,关键字true和false就会被替换成1和0。
from eg.Cat cat where cat.alive = true
你可以用特殊属性size来测试一个集合的长度,或者用特殊的size()函数也可以。
from eg.Cat cat where cat.kittens.size > 0
from eg.Cat cat where size(cat.kittens) > 0
对于排序集合,你可以用minIndex和maxIndex来获取其最大索引值和最小索引值。类似的,minElement 和maxElement 可以用来获取集合中最小和最大的元素,前提是必须是基本类型的集合。
from Calendar cal where cal.holidays.maxElement > current date
也有函数的形式(和上面的形式不同,函数形式是大小写不敏感的):
from Order order where maxindex(order.items) > 100
from Order order where minelement(order.items) > 10000
SQL中的any, some, all, exists, in功能也是支持的,前提是必须把集合的元素或者索引集作为它们的参数(使用element和indices函数),或者使用子查询的结果作为参数。
select mother from eg.Cat as mother, eg.Cat as kit
where kit in elements(foo.kittens)
select p from eg.NameList list, eg.Person p
where p.name = some elements(list.names)
from eg.Cat cat where exists elements(cat.kittens)
from eg.Player p where 3 > all elements(p.scores)
from eg.Show show where 'fizard' in indices(show.acts)
请注意这些设施:size,elements,indices,minIndex,maxIndex,minElement,maxElement 都有一些使用限制:
在where子句中: 只对支持子查询的数据库有效
在select子句中:只有elements和indices有效
有序的集合(数组、list、map)的元素可以用索引来进行引用(只限于在where子句中)
from Order order where order.items[0].id = 1234
select person from Person person, Calendar calendar
where calendar.holidays['national day'] = person.birthDay
and person.nationality.calendar = calendar
select item from Item item, Order order
where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11
select item from Item item, Order order
where order.items[ maxindex(order.items) ] = item and order.id = 11
[]中的表达式允许是另一个数学表达式。
select item from Item item, Order order
where order.items[ size(order.items) - 1 ] = item
HQL也对一对多关联或者值集合提供内置的index()函数。
select item, index(item) from Order order
join order.items item
where index(item) < 5
底层数据库支持的标量SQL函数也可以使用
from eg.DomesticCat cat where upper(cat.name) like 'FRI%'
假如以上的这些还没有让你信服的话,请想象一下下面的查询假若用SQL来写,会变得多么长,多么不可读:
select cust
from Product prod,
Store store
inner join store.customers cust
where prod.name = 'widget'
and store.location.name in ( 'Melbourne', 'Sydney' )
and prod = all elements(cust.currentOrder.lineItems)
提示:对应的SQL语句可能是这样的
SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
FROM customers cust,
stores store,
locations loc,
store_customers sc,
product prod
WHERE prod.name = 'widget'
AND store.loc_id = loc.id
AND loc.name IN ( 'Melbourne', 'Sydney' )
AND sc.store_id = store.id
AND sc.cust_id = cust.id
AND prod.id = ALL(
SELECT item.prod_id
FROM line_items item, orders o
WHERE item.order_id = o.id
AND cust.current_order = o.id
)
10.9. order by 子句
查询返回的列表可以按照任何返回的类或者组件的属性排序:
from eg.DomesticCat cat
order by cat.name asc, cat.weight desc, cat.birthdate
asc和desc是可选的,分别代表升序或者降序。
10.10. group by 子句
返回统计值的查询可以按照返回的类或者组件的任何属性排序:
select cat.color, sum(cat.weight), count(cat)
from eg.Cat cat
group by cat.color
select foo.id, avg( elements(foo.names) ), max( indices(foo.names) )
from eg.Foo foo
group by foo.id
请注意:你可以在select子句中使用elements和indices指令,即使你的数据库不支持子查询也可以。
having子句也是允许的。
select cat.color, sum(cat.weight), count(cat)
from eg.Cat cat
group by cat.color
having cat.color in (eg.Color.TABBY, eg.Color.BLACK)
在having子句中允许出现SQL函数和统计函数,当然这需要底层数据库支持才行。(比如说,MySQL就不支持)
select cat
from eg.Cat cat
join cat.kittens kitten
group by cat
having avg(kitten.weight) > 100
order by count(kitten) asc, sum(kitten.weight) desc
注意,group by子句和order by子句都不支持数学表达式。
10.11. 子查询
对于支持子查询的数据库来说,Hibernate支持在查询中嵌套子查询。子查询必须由圆括号包围(常常是在一个SQL统计函数中)。也允许关联子查询(在外部查询中作为一个别名出现的子查询)。
from eg.Cat as fatcat
where fatcat.weight > (
select avg(cat.weight) from eg.DomesticCat cat
)
from eg.DomesticCat as cat
where cat.name = some (
select name.nickName from eg.Name as name
)
from eg.Cat as cat
where not exists (
from eg.Cat as mate where mate.mate = cat
)
from eg.DomesticCat as cat
where cat.name not in (
select name.nickName from eg.Name as name
)
10.12. 示例
Hibernate查询可以非常强大复杂。实际上,强有力的查询语言是Hibernate的主要卖点之一。下面给出的示例与我在近期实际项目中使用的一些查询很类似。请注意你编写的查询大部分等都不会这么复杂!
下面的查询对特定的客户,根据给定的最小总计值(minAmount),查询出所有未付订单,返回其订单号、货品总数、订单总金额,结果按照总金额排序。在决定价格的时候,参考当前目录。产生的SQL查询,在ORDER,ORDER_LINE,PRODUCT,CATALOG和PRICE表之间有四个内部连接和一个没有产生关联的字查询。
select order.id, sum(price.amount), count(item)
from Order as order
join order.lineItems as item
join item.product as product,
Catalog as catalog
join catalog.prices as price
where order.paid = false
and order.customer = :customer
and price.product = product
and catalog.effectiveDate < sysdate
and catalog.effectiveDate >= all (
select cat.effectiveDate
from Catalog as cat
where cat.effectiveDate < sysdate
)
group by order
having sum(price.amount) > :minAmount
order by sum(price.amount) desc
好家伙,真长!实际上,在现实生活中我并不是非常热衷于子查询,所以我的查询往往是这样的:
select order.id, sum(price.amount), count(item)
from Order as order
join order.lineItems as item
join item.product as product,
Catalog as catalog
join catalog.prices as price
where order.paid = false
and order.customer = :customer
and price.product = product
and catalog = :currentCatalog
group by order
having sum(price.amount) > :minAmount
order by sum(price.amount) desc
下面的查询统计付款记录处于每种状态中的数量,要排除所有处于AWAITING_APPROVAL状态的,或者最近一次状态更改是由当前用户做出的。它翻译成SQL查询后,在PAYMENT,PAYMENT_STATUS和PAYMENT_STATUS_CHANGE表之间包含两个内部连接和一个用于关联的子查询。
select count(payment), status.name
from Payment as payment
join payment.currentStatus as status
join payment.statusChanges as statusChange
where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
or (
statusChange.timeStamp = (
select max(change.timeStamp)
from PaymentStatusChange change
where change.payment = payment
)
and statusChange.user <> :currentUser
)
group by status.name, status.sortOrder
order by status.sortOrder
假若我已经把statusChange集合映射为一个列表而不是一个集合的话,查询写起来会简单很多。
select count(payment), status.name
from Payment as payment
join payment.currentStatus as status
where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser
group by status.name, status.sortOrder
order by status.sortOrder
下面的查询使用了MS SQL Server的isNull()函数,返回当前用户所属的组织所有账户和未付支出。翻译为SQL查询后,在ACCOUNT, PAYMENT, PAYMENT_STATUS,ACCOUNT_TYPE, ORGANIZATION 和 ORG_USER表之间有三个内部连接,一个外部连接和一个子查询。
select account, payment
from Account as account
left outer join account.payments as payment
where :currentUser in elements(account.holder.users)
and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
order by account.type.sortOrder, account.accountNumber, payment.dueDate
对某些数据库而言,我们可能不能依赖(关联的)子查询。
select account, payment
from Account as account
join account.holder.users as user
left outer join account.payments as payment
where :currentUser = user
and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
order by account.type.sortOrder, account.accountNumber, payment.dueDate
10.13. 提示和技巧(Tips & Tricks)
你不返回结果集也可以查询结果集的大小:
( (Integer) session.iterate("select count(*) from ....").next() ).intValue()
要依据一个集合的大小对结果集排序,可以用下面的查询来对付一对多或多对多的关联:
select usr
from User as usr
left join usr.messages as msg
group by usr
order by count(msg)
如果你的数据库支持子查询,你可以在查询的where子句中对选择的大小进行条件限制:
from User usr where size(usr.messages) >= 1
如果你的数据库不支持子查询,可以使用下列查询:
select usr.id, usr.name
from User usr.name
join usr.messages msg
group by usr.id, usr.name
having count(msg) >= 1
因为使用了inner join,这个解决方法不能返回没有message的User.下面的方式就可以:
select usr
from User as usr
left join usr.messages as msg
group by usr
having count(msg) = 0
JavaBean的属性可以直接作为命名的查询参数:
Query q = s.createQuery("from foo in class Foo where foo.name=:name and foo.size=:size");
q.setProperties(fooBean); // fooBean has getName() and getSize()
List foos = q.list();
在Query接口中使用过滤器(filter),可以对集合分页:
Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();
集合元素可以使用查询过滤器(query filter)进行排序或者分组:
List orderedCollection = s.filter( collection, "order by this.amount" );
List counts = s.filter( collection, "select this.type, count(this) group by this.type" );
不用初始化集合就可以得到其大小:
( (Integer) session.iterate("select count(*) from ....").next() ).intValue();
相关推荐
### Hibernate HQL 关联查询详解 #### 一、引言 在进行数据库操作时,关联查询是必不可少的一部分,尤其在处理复杂的数据结构时更是如此。Hibernate作为一种流行的Java持久层框架,提供了强大的对象关系映射(ORM...
《Hibernate HQL查询语法详解》 Hibernate,作为Java领域中广泛应用的对象关系映射(ORM)框架,极大地简化了数据库操作。其内置的HQL(Hibernate Query Language)是一种面向对象的查询语言,它允许开发者以类和...
### Hibernate HQL 查询详解 #### 一、HQL(Hibernate Query Language)简介 HQL(Hibernate Query Language)是一种面向对象的查询语言,它允许开发者使用类及其属性来编写查询语句,而不是传统的SQL语句。这使得...
### Hibernate HQL 查询详解 #### 一、HQL 概述 Hibernate 提供了一种非常强大的查询语言——HQL(Hibernate Query Language),它在语法上与 SQL 类似但功能更为强大,因为它支持面向对象的特性,例如继承、多态性...
### Hibernate HQL 基本查询详解 #### 一、HQL 概述 HQL (Hibernate Query Language) 是一种面向对象的查询语言,由 Hibernate 官方提供,用于简化数据库查询过程。与传统的 JDBC 方式相比,使用 HQL 进行数据库...
Hibernate HQL,全称为Hibernate Query Language,是Hibernate框架中用于操作数据库的一种面向对象的查询语言。它允许开发者用面向对象的方式来编写查询语句,极大地提高了开发效率和代码的可读性。以下是对HQL的...
本程序“HibernateHql综合测试小程序”是针对Hibernate中的HQL(Hibernate Query Language)进行的一系列功能测试,涵盖了二十多种不同的HQL语句,旨在帮助开发者深入理解和熟练运用Hibernate的查询能力。...
下面是一个简单的Java程序示例,展示了如何在Java中使用Hibernate框架执行HQL查询: ```java import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate....
其中,Hibernate Query Language(HQL)是Hibernate提供的面向对象的查询语言,类似于SQL,但更贴近Java编程模型。本文将深入探讨HQL在查询映射对象及字段方面的基本用法。 1. 查询整个映射对象所有字段 在...
### Hibernate HQL 基本操作详解 #### 一、HQL简介 HQL,即Hibernate Query Language,是Hibernate提供的一种强大的查询语言。虽然它的语法结构看起来与SQL类似,但其实质上是一种面向对象的语言,能够理解并处理...
这里使用了HQL(Hibernate Query Language)来执行查询。例如,在`getProductsMenuSub`方法中,通过以下HQL语句实现了连表查询: ```java String queryString = "select a.productsName from TopProducts as a, ...
《精通Hibernate:Java对象持久化详解》是一本深入解析Hibernate技术的专著,它主要针对Java开发者,旨在帮助他们理解和掌握Java对象持久化的精髓。Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了...
### HQL查询详解 HQL(Hibernate Query Language)是一种面向对象的查询语言,它提供了与SQL类似的功能,但更贴近于面向对象编程的思维方式。HQL允许开发人员以一种更自然的方式查询数据库,同时保持了Java对象模型...
hibernate查询详解 在Java开发中,Hibernate作为一款强大的ORM(Object-Relational Mapping)框架,极大地简化了数据库操作。本文将详细介绍Hibernate的五种查询方式,包括HQL查询、Criteria方法、动态查询...
### Hibernate教程:数据查询与HQL详解 #### 引言 Hibernate是一款强大的对象关系映射(ORM)框架,它能够将Java对象与数据库表进行映射,极大地简化了数据库操作的复杂度。在数据查询方面,Hibernate提供了多种...
在探讨HQL(Hibernate Query Language)时,我们首先要了解它是一种用于Hibernate框架中的查询语言,其语法结构与标准SQL查询语言非常相似,但又针对对象关系映射(ORM)进行了优化。本文将详细介绍HQL的基本用法...
### Hibernate HQL 语句详解 #### HQL (Hibernate Query Language) 概述 HQL是一种专门为Hibernate设计的查询语言,其语法结构接近于标准SQL,但又具有面向对象的特性。HQL允许开发者以一种更为简洁、直观的方式...
HQL(Hibernate Query Language)是Hibernate提供的查询语言,它提供了丰富的查询功能。HQL作为推荐的标准查询方式,在HQL查询过程中,它不仅支持标准SQL查询语法,还提供了一种面向对象的封装方式。HQL在Hibernate...
此外,还有其他的高级配置,如查询语言(HQL)的设置、是否启用自动更新或创建数据库结构等: ```xml <property name="hibernate.hbm2ddl.auto">update ``` 这个属性可以设置为`create`、`create-drop`、`update`或`...