子查询是SQL中很重要的功能,他可以在SQL中利用另外一条SQL的查询结果,HQL同样支持此机制
如果子查询返回都条记录,可以用以下关键字进行量化
all: 表示所有记
any:表示所有记录中的任意1条
some:与any用法一样
in:与=any等价
exist: 表示子查询至少要返回一条记录
数据库结构:

create
table
testStu (id
varchar
(
32
),name
varchar
(
32
),age
int
,team_id
varchar
(
32
));

insert
into
teststu
values
("
1
","tom1",
11
,"
1
");
insert
into
teststu
values
("
2
","tom2",
12
,"
2
");
insert
into
teststu
values
("
3
","tom3",
13
,"
1
");
insert
into
teststu
values
("
4
","tom4",
14
,"
2
");
insert
into
teststu
values
("
5
","tom5",
15
,"
1
");
insert
into
teststu
values
("
6
","tom6",
16
,"
2
");
insert
into
teststu
values
("
7
","tom7",
17
,"
1
");
insert
into
teststu
values
("
8
","tom8",
18
,"
2
");
insert
into
teststu
values
("
9
","tom9",
19
,"
1
");
insert
into
teststu
values
("
10
","tom10",
20
,"
2
");


create
table
testteam (id
varchar
(
32
)
primary
key
,name
varchar
(
32
));

insert
into
testteam
values
("
1
","team1");
insert
into
testteam
values
("
2
","team2");

POJO:
package
Search.filter;


public
class
TestStu
...
{
private String id; //标识id
private String name; //学生姓名
private int age; //岁数
private TestTeam team;


public int getAge() ...{
return age;
}


public String getName() ...{
return name;
}




public void setId(String id) ...{
this.id = id;
}


public void setAge(int age) ...{
this.age = age;
}


public void setName(String stuName) ...{
this.name = stuName;
}




public String getId() ...{
return id;
}


public TestStu() ...{ //无参的构造函数
}


public TestTeam getTeam() ...{
return team;
}


public void setTeam(TestTeam team) ...{
this.team = team;
}

}


package
Search.filter;

import
java.util.Set;


public
class
TestTeam
...
{
private String id;
private String name;
private Set students;

public String getId() ...{
return id;
}

public void setId(String id) ...{
this.id = id;
}

public String getName() ...{
return name;
}

public void setName(String name) ...{
this.name = name;
}

public Set getStudents() ...{
return students;
}

public void setStudents(Set students) ...{
this.students = students;
}
}
Hibernate.cfg.xml
<?
xml version='1.0' encoding='UTF-8'
?>
<!
DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
>

<!--
Generated by MyEclipse Hibernate Tools.
-->
<
hibernate-configuration
>

<
session-factory
>
<
property
name
="connection.username"
>
root
</
property
>
<
property
name
="connection.url"
>
jdbc:mysql://localhost:3306/schoolproject?characterEncoding=gb2312
&
useUnicode=true
</
property
>
<
property
name
="dialect"
>
org.hibernate.dialect.MySQLDialect
</
property
>
<
property
name
="myeclipse.connection.profile"
>
mysql
</
property
>
<
property
name
="connection.password"
>
1234
</
property
>
<
property
name
="connection.driver_class"
>
com.mysql.jdbc.Driver
</
property
>
<
property
name
="hibernate.dialect"
>
org.hibernate.dialect.MySQLDialect
</
property
>
<
property
name
="hibernate.show_sql"
>
true
</
property
>
<
property
name
="current_session_context_class"
>
thread
</
property
>
<
mapping
resource
="Search/sub/TestStu.hbm.xml"
/>
<
mapping
resource
="Search/sub/TestTeam.hbm.xml"
/>

</
session-factory
>

</
hibernate-configuration
>
TestStu.hbm.xml
<?
xml version="1.0" encoding="utf-8"
?>
<!
DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<
hibernate-mapping
package
="Search.fetch"
>
<
class
name
="Search.sub.TestStu"
table
="teststu"
lazy
="true"
>
<
id
name
="id"
column
="id"
unsaved-value
="null"
>
<
generator
class
="uuid.hex"
></
generator
>
</
id
>

<
property
name
="name"
column
="name"
></
property
>
<
property
name
="age"
column
="age"
></
property
>
<
many-to-one
name
="team"
column
="team_id"
>
</
many-to-one
>
</
class
>
</
hibernate-mapping
>
TestTeam.hbm.xml
<?
xml version="1.0" encoding="utf-8"
?>
<!
DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<
hibernate-mapping
>
<
class
name
="Search.sub.TestTeam"
table
="testteam"
lazy
="true"
>
<
id
name
="id"
column
="id"
unsaved-value
="null"
>
<
generator
class
="uuid.hex"
></
generator
>
</
id
>
<
property
name
="name"
column
="name"
type
="string"
></
property
>
<
set
name
="students"
inverse
="true"
lazy
="true"
fetch
="select"
>
<
key
column
="team_id"
></
key
>
<
one-to-many
class
="Search.sub.TestStu"
/>

</
set
>
</
class
>

</
hibernate-mapping
>
测试代码:
package
Search.sub;

import
java.io.File;
import
java.util.Iterator;
import
java.util.List;

import
org.hibernate.Query;
import
org.hibernate.Session;
import
org.hibernate.SessionFactory;
import
org.hibernate.Transaction;
import
org.hibernate.cfg.Configuration;


public
class
Test
...
{



public static void main(String[] args)...{
String filePath=System.getProperty("user.dir")+File.separator+"src/Search/sub"+File.separator+"hibernate.cfg.xml";
File file=new File(filePath);
SessionFactory sessionFactory=new Configuration().configure(file).buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction t=(Transaction)session.beginTransaction();
//查询所有学生年龄都大于11岁的班级对象(结果应为team2)
//team1学生年龄是11,13,15,17,19
//team2学生年龄是12,14,16,17,20

/**//*
* 使用SQL
* select t1.name
from testteam t1
where 11<all(SELECT s.age from teststu s where s.team_id=t1.id);
*/
Query query=session.createQuery("from TestTeam t where 11<all(select s.age from t.students s)");
//注意:不能将11<all 写成all>11以违反Mysql规则
List teamList=query.list();

for (Iterator iterator = teamList.iterator(); iterator.hasNext();) ...{
TestTeam object = (TestTeam) iterator.next();
System.out.println(object.getName());
}
//查询有一个学生的年龄为15岁的team对象(结果应为team1)

/**//*
* 使用SQL
* select t1.name
from testteam t1
where 15=any(SELECT s.age from teststu s where s.team_id=t1.id);
*/
Query query1=session.createQuery("from TestTeam t where 15=any(select s.age from t.students s)");
List teamList1=query1.list();

for (Iterator iterator = teamList1.iterator(); iterator.hasNext();) ...{
TestTeam object1 = (TestTeam) iterator.next();
System.out.println(object1.getName());
}
t.commit();

}

}
运行结果:
Hibernate: select testteam0_.id as id1_, testteam0_.name as name1_ from testteam testteam0_ where 11<all (select students1_.age from teststu students1_ where testteam0_.id=students1_.team_id)
team2
Hibernate: select testteam0_.id as id1_, testteam0_.name as name1_ from testteam testteam0_ where 15=any (select students1_.age from teststu students1_ where testteam0_.id=students1_.team_id)
team1
HQL子查依赖底层数据库的子查询能力,所以,要根据所使用的数据库来决定是否是用你HQL子查询,为了更多的移植性,最好使用连接查询和分组查询代替子查询