hibernate 连接查询
三、连接查询
HQL和QBC支持的各种连接类型
在程序中指定的链接查询类型
HQL语法
QBC语法
使用范围
内连接
innerjoin或者join
Criteria.createAlias()
适用于有关联的持久化类,并且在映射文件中对这种关联关系作了映射。
迫切内连接
innerjoinfetch或者joinfetch
不支持
隐式内连接
不支持
左外连接
leftouterjoin或者leftjoin
不支持
迫切左外连接
leftouterjoinfetch或者leftjoinfetch
FetchMode.EAGER
右外连接
rightouterjoin或者rightjoin
不支持
交叉连接
ClassA,ClassB
不支持
适用于不存在关联关系的持久化类
1、默认情况下关联级别的运行时检索策略
采用配置文件中设置的检索策略,但有一个例外,那就是HQL会忽略映射文件设置的迫切左外连接策略,改用立即检索。
2、迫切左外连接
显式指定对象的关联关系为迫切左外连接检索策略,可以覆盖映射文件中指定的检索策略。
例HQL
"fromCustomercleftjoinfetchc.ordersowherec.namelike't%'"
+"o.namelike't%'"
例QBC
Listreslut=session.createCriteria(Customer.class).setFetchMode("orders",FetchMode.EAGER).add(Expression.like("name","t",MatchMode.START))
.list();
当使用迫切左外连接检索策略时,查询结果中可能会包含重复元素,可以通过一个HashSet来过滤重复元素:Listresult=….list();HashSetset=newHashSet(result);
Hibernate允许在一条查询语句中迫切左外连接多个多对一或一对一关联的类。
Listreslut=session.createCriteria(A.class).setFetchMode("this.b",FetchMode.EAGER).setFetchMode("this.c",FetchMode.EAGER).add(Expression.isNotNull("this.b")).add(Expression.isNotNull("this.c"))
.list();
当存在传递关联时,可以通过HQL来同时迫切左外连接关联类和依赖关联类,但QBC无法表达这种形式的迫切左外连接。
3、左外连接
使用左外连接查询时,将根据映射文件的配置来决定关联的检索策略。
4、内连接
QBC也支持内连接查询
Listreslut=session.createCriteria(Customer.class).add(Expression.like("name","t",MatchMode.SRART)).createCriteria("orders").add(Expression.like("orderNumber","t",MatchMode.SRART))
.list();
默认情况下,QBC只检索出Customer对象,以上代码等同于以下HQL查询语句:
"selectcfromCustomercjoinc.ordersowherec.namelike't%'"
+"ando.orderNumberlike't%'";
createAlias()方法为关联属性(集合)赋予别名。如果希望QBC返回的集合也包含成对的Customer和Order对象,可以调用returnMaps()方法:
Listreslut=session.createCriteria(Customer.class).createAlias("orders","o").add(Expression.like("this.name","t",MatchMode.SRART)).add(Expression.like("o.orderNumber","t",MatchMode.SRART)).returnMaps()
.list();
采用内连接查询时,HQL与QBC有不同的默认行为,前者检索成对的对象,后者仅检索出要检索的单个对象(不包含关联的对象)。
5、迫切内连接
显式指定对象的关联关系为迫切内连接检索策略,可以覆盖映射文件中指定的检索策略。
6、隐式内连接
一对一
"fromCunstomercwherec.homeAddress.provicelike'%hai%'"
Listreslut=session.createCriteria(Customer.class).add(Expression.like("homeAddress.provice","t",MatchMode.SRART))
.list();
多对一
"fromOrderowhereo.customer.namelike'%hai%'"
QBC不支持隐式内连接,下边是不正确的,:
Listreslut=session.createCriteria(Order.class).add(Expression.like("customer.name","t",MatchMode.SRART))
.list();
对于QBC,必须显式指定内连接查询:
Listreslut=session.createCriteria(Order.class).createAlias("customer","c").add(Expression.like("c.name","t",MatchMode.SRART))
.list();
一对多或多对多
隐式内连接不适用。
7、右外连接
8、使用SQL风格的交叉连接和隐式内连接
HQL支持SQL风格的交叉连接查询。如:fromCustomerc,Ordero
在SQL语言中,显式内连接查询的语句使用innerjoin关键字,并且用on字句设定连接条件,形式为:
"select*fromCUSTOMERcinnerjoinORDERoonc.ID=o.CUSTOMER_ID"
隐式内连接查询语句不包含关键字阿,并且用where字句设定连接条件:
"select*fromCUSTOMERc,ORDERowherec.ID=o.CUSTOMER_ID"
9、关联级别运行是的检索策略
(1)没有显式指定,使用配置文件的,但有一个例外,那就是HQL会忽略映射文件设置的迫切左外连接策略,改用立即检索。
(2)如果显式指定,就会覆盖映射文件配置的检索策略。在HQL查询语句中显式指定检索策略包括以下内容。
lleftjoinfetch
linnerjoinfetch
QBC通过FetchMode类来显式指定检索策略,有以下3个静态实例。
lFetchMode.DEFAULT:默认,采用配置;
lFetchMode.EAGER:覆盖,指定迫切左外连接检索策略;
lFetchMode.LAZY:覆盖映射配置文件的检索策略,在程序中指定延迟检索策略。
待续!