把HQL语句或SQL语句写在Hibernate实体类对应的映射文件中的使用。
打开Hibernate的Session的源码,我们可以看到有一个getNamedQuery(String name);的方法,如下:
1
2
3
4
5
6
7
8
9
|
/**
* Obtain an instance of <tt>Query</tt> for a named query string defined in the
* mapping file.
*
* @param queryName the name of a query defined externally
* @return Query
* @throws HibernateException
*/
public
Query getNamedQuery(String queryName)
throws
HibernateException;
|
这个方法就是可以执行定义在Hibernate实体类映射文件中的HQL或Sql语句。
具体做法下面我一一讲解,首先测试在映射文件中定义HQL语句。
我在User实体类的映射文件中定义了一个name为getUserByName的HQL查询语句,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?
xml
version
=
"1.0"
?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"D:\tools\hibernate\dtd\hibernate-mapping-3.0.dtd">
<
hibernate-mapping
package
=
"com.xigua.domain"
>
<
class
name
=
"User"
>
<
id
name
=
"id"
>
<
generator
class
=
"native"
/>
</
id
>
<
property
name
=
"name"
/>
<
property
name
=
"birthday"
/>
</
class
>
<!-- 定义一个查询,名称为getUserByName -->
<
query
name
=
"getUserByName"
>
<![CDATA[from User where name = :name]]>
</
query
>
</
hibernate-mapping
>
|
然后编写测试类使用Session中的getNamedQuery(String name)方法进行测试,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package
com.xigua.test;
import
java.util.Date;
import
java.util.List;
import
org.hibernate.Query;
import
org.hibernate.Session;
import
org.hibernate.Transaction;
import
com.xigua.domain.User;
import
com.xigua.utils.HibernateUtil;
public
class
Test9 {
public
static
void
main(String[] args) {
addUser();
String name =
"xigua"
;
List<User> list = namedQuery(name);
if
(list !=
null
&& !list.isEmpty()) {
for
(User user : list) {
System.out.println(user.getId() +
", "
+ user.getName() +
", "
+ user.getBirthday());
}
}
}
public
static
void
addUser() {
Session session =
null
;
Transaction tx =
null
;
try
{
session = HibernateUtil.getSession();
tx = session.beginTransaction();
User user =
new
User();
user.setName(
"xigua"
);
user.setBirthday(
new
Date());
session.save(user);
user =
new
User();
user.setName(
"donggua"
);
user.setBirthday(
new
Date());
session.save(user);
tx.commit();
}
catch
(Exception e) {
if
(tx !=
null
) {
tx.rollback();
}
}
finally
{
if
(session !=
null
) {
session.close();
}
}
}
public
static
List<User> namedQuery(String name) {
Session session =
null
;
try
{
session = HibernateUtil.getSession();
Query query = session.getNamedQuery(
"getUserByName"
);
query.setParameter(
"name"
, name);
return
query.list();
}
catch
(Exception e) {
e.printStackTrace();
}
finally
{
if
(session !=
null
) {
session.close();
}
}
return
null
;
}
}
|
在映射文件中除了可以定义HQL语句,也还是可以定义Sql语句的。
前面的User实体类的映射文件修改如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?
xml
version
=
"1.0"
?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"D:\tools\hibernate\dtd\hibernate-mapping-3.0.dtd">
<
hibernate-mapping
package
=
"com.xigua.domain"
>
<
class
name
=
"User"
>
<
id
name
=
"id"
>
<
generator
class
=
"native"
/>
</
id
>
<
property
name
=
"name"
/>
<
property
name
=
"birthday"
/>
</
class
>
<!-- 定义一个查询,名称为getUserByName
<query name="getUserByName">
<![CDATA[from User where name = :name]]>
</query>
-->
<
sql-query
name
=
"getUserByName"
>
<![CDATA[select id, name from user where name = :name]]>
</
sql-query
>
</
hibernate-mapping
>
|
测试代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
package
com.xigua.test;
import
java.util.Date;
import
org.hibernate.Query;
import
org.hibernate.Session;
import
org.hibernate.Transaction;
import
com.xigua.domain.User;
import
com.xigua.utils.HibernateUtil;
public
class
Test10 {
public
static
void
main(String args[]) {
addUser();
String name =
"xigua"
;
User user = namedSqlQuery(name);
if
(user !=
null
) {
System.out.println(user.getId() +
", "
+ user.getName());
}
}
public
static
void
addUser() {
Session session =
null
;
Transaction tx =
null
;
try
{
session = HibernateUtil.getSession();
tx = session.beginTransaction();
User user =
new
User();
user.setName(
"xigua"
);
user.setBirthday(
new
Date());
session.save(user);
user =
new
User();
user.setName(
"donggua"
);
user.setBirthday(
new
Date());
session.save(user);
tx.commit();
}
catch
(Exception e) {
if
(tx !=
null
) {
tx.rollback();
}
}
finally
{
if
(session !=
null
) {
session.close();
}
}
}
public
static
User namedSqlQuery(String name) {
Session session =
null
;
try
{
session = HibernateUtil.getSession();
Query query = session.getNamedQuery(
"getUserByName"
);
query.setParameter(
"name"
, name);
Object[] obj = (Object[]) query.uniqueResult();
if
(obj !=
null
) {
User user =
new
User();
user.setId(Long.valueOf(obj[
0
].toString()));
user.setName(obj[
1
].toString());
return
user;
}
}
catch
(Exception e) {
e.printStackTrace();
}
finally
{
if
(session !=
null
) {
session.close();
}
}
return
null
;
}
}
|
映射文件中还有些其它的配置,暂时还没具体搞懂,比如下面红色的代码:
1
2
3
4
5
6
7
8
|
<sql-query name=
"getUserByName"
>
<![CDATA[select id, name from user where name = :name]]>
<query-param name=
"name"
type=
"string"
/>
<
return
></
return
>
<
return
-join alias=
""
property=
""
></
return
-join>
<
return
-scalar column=
""
/>
<synchronize table=
""
/>
</sql-query>
|
还有一点像说明的是<query>跟<sql-query>的配置是可以放到<class>节点里面的。
我现在是放在<class>节点外面,表示全局可用,这里需要注意不要跟其它映射文件中定义的<query>或<sql-query>同名。
如果将<query>或<sql-query>放在<class>节点里面,在java代码中使用的时候需要将package名跟class名都写上,具体见下面配置的映射文件代码跟测试代码。
映射文件代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?
xml
version
=
"1.0"
?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"D:\tools\hibernate\dtd\hibernate-mapping-3.0.dtd">
<
hibernate-mapping
package
=
"com.xigua.domain"
>
<
class
name
=
"User"
>
<
id
name
=
"id"
>
<
generator
class
=
"native"
/>
</
id
>
<
property
name
=
"name"
/>
<
property
name
=
"birthday"
/>
<!-- 定义一个查询,名称为getUserByName (这里将<query>放到<class>节点里面来)-->
<
query
name
=
"getUserByName"
>
<![CDATA[from User where name = :name]]>
</
query
>
</
class
>
</
hibernate-mapping
>
|
java测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package
com.xigua.test;
import
java.util.Date;
import
java.util.List;
import
org.hibernate.Query;
import
org.hibernate.Session;
import
org.hibernate.Transaction;
import
com.xigua.domain.User;
import
com.xigua.utils.HibernateUtil;
public
class
Test9 {
public
static
void
main(String[] args) {
addUser();
String name =
"xigua"
;
List<User> list = namedQuery(name);
if
(list !=
null
&& !list.isEmpty()) {
for
(User user : list) {
System.out.println(user.getId() +
", "
+ user.getName() +
", "
+ user.getBirthday());
}
}
}
public
static
void
addUser() {
Session session =
null
;
Transaction tx =
null
;
try
{
session = HibernateUtil.getSession();
tx = session.beginTransaction();
User user =
new
User();
user.setName(
"xigua"
);
user.setBirthday(
new
Date());
session.save(user);
user =
new
User();
user.setName(
"donggua"
);
user.setBirthday(
new
Date());
session.save(user);
tx.commit();
}
catch
(Exception e) {
if
(tx !=
null
) {
tx.rollback();
}
}
finally
{
if
(session !=
null
) {
session.close();
}
}
}
public
static
List<User> namedQuery(String name) {
Session session =
null
;
try
{
session = HibernateUtil.getSession();
Query query = session.getNamedQuery(
"com.xigua.domain.User.getUserByName"
);
query.setParameter(
"name"
, name);
return
query.list();
}
catch
(Exception e) {
e.printStackTrace();
}
finally
{
if
(session !=
null
) {
session.close();
}
}
return
null
;
}
}
|