Hibernate的命名查询(NamedQuery)

把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 ;
     }
 
}






转载于:https://my.oschina.net/mickeymouse/blog/518687

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值