`
xigua366
  • 浏览: 102453 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Hibernate的命名查询(NamedQuery)

阅读更多

做了四年的JavaEE开发,用了hibernate四年,今天才知道,原来还可以把HQL语句或SQL语句写在Hibernate实体类对应的映射文件中的。

打开Hibernate的Session的源码,我们可以看到有一个getNamedQuery(String name);的方法,如下:

/**
	 * 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查询语句,代码如下:

<?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)方法进行测试,代码如下:

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实体类的映射文件修改如下:

<?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>

 

测试代码如下:

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

}

 

映射文件中还有些其它的配置,暂时还没具体搞懂,比如下面红色的代码:

<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名都写上,具体见下面配置的映射文件代码跟测试代码。

映射文件代码:

<?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测试代码(注意下图红色部分字符串)

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

}

 

1
0
分享到:
评论

相关推荐

    hibernate自定义查询

    Hibernate的自定义查询能力极大地提高了开发效率,通过HQL、命名查询、Criteria API和直接SQL查询,我们可以根据项目需求选择最合适的方式来处理数据。`QueryDAO`和`QueryNamedDAO`的实现细节可能包含了对这些查询...

    Hibernate查询方式代码示例

    在`hibernate.cfg.xml`或实体类的`@NamedQuery`注解中定义命名查询: ```xml &lt;query name="getStudentsOverAge"&gt; FROM Student WHERE age &gt; 20 &lt;/query&gt; ``` 在代码中使用: ```java Query query = session...

    Hibernate_query查询数据表中部分字段.

    5. **命名查询(Named Queries)**: 如果某些查询模式经常被使用,可以定义命名查询,将其写入XML映射文件中,以提高代码可读性和复用性。 6. **动态HQL**: 对于更动态的查询,可以构建HQL字符串,但这可能会...

    hibernate公共查询

    - `findByNamedQuery(queryName, params)`: 使用预定义的命名查询,这些查询可以在`hbm.xml`映射文件中定义,或通过`@NamedQuery`注解在实体类上声明。 - `countByExample(entity)`: 计算满足特定条件的记录数,...

    hibernate annotation hibernate3

    @NamedQuery(name="User.findAll", query="SELECT u FROM User u") ``` 2. `@Query` JPA的动态查询,可以直接在注解中编写HQL或JPQL查询语句。 六、事务管理注解 1. `@Transactional` 标记在方法上,表示该...

    hibernate查询语言--HQL

    public void namedQuery(Session session) { Query&lt;Student&gt; query = session.getNamedQuery("findStudentsByName"); query.setParameter(0, "John Doe"); List&lt;Student&gt; students = query.list(); // 处理查询...

    Hibernate查询语句写在配置文件中

    在配置文件中,你可以定义命名查询(Named Query),例如: ```xml &lt;hibernate-mapping&gt; &lt;!-- class mapping details --&gt; &lt;query name="findUsersByName"&gt; &lt;![CDATA[from User as u where u.name = ?]]&gt; &lt;/...

    Hibernate查询语句统一配置管理.doc

    例如,可以直接在Entity类上使用`@NamedQuery`和`@NamedNativeQuery`注解来定义HQL和SQL查询,这种方式更具有代码内联性,但可能会增加实体类的复杂性。 【优点总结】 1. 维护分层架构:将查询语句集中管理,避免...

    本人写的Hibernate超级通用DAO

    以及`List&lt;T&gt; findByNamedQuery(String namedQuery, Map, Object&gt; params)`,使用预定义的命名查询。 3. **分页查询**:在大型项目中,通常需要实现分页功能,我们可以提供`List&lt;T&gt; findPage(int pageSize, int ...

    hibernate annotation 中文文档

    - `@NamedQuery`: 预定义命名查询,可以在多个地方重用。 7. **缓存** - `@Cacheable`: 标记实体类或方法支持缓存,提高性能。 - `@Cache`: 配置缓存区域和策略,如读写策略、时间戳等。 8. **转换器与自定义...

    hibernate annotaion api 中文与英文版

    - `@NamedQuery`: 预编译的命名查询,可以在多个地方重复使用。 **8. 最新版本与兼容性** Hibernate Annotation API的最新版本通常与Hibernate ORM保持同步,提供更多的特性和改进。确保你的项目使用的是与所使用的...

    hibernate全面总结文档

    - 命名查询(Named Query)是预定义的 HQL 查询,可以在 XML 映射文件中定义,然后通过 `session.getNameQuery("queryName")` 调用。 7. **查询结果处理**: - `uniqueResult()` 返回查询结果的唯一对象,如果...

    HibernateAPI

    命名查询(Named Query)是预先定义在映射文件或实体类上的HQL或SQL查询,可提高代码的可读性和可维护性。 10. **缓存机制** Hibernate 提供了第一级缓存(Session级别)和第二级缓存(SessionFactory级别)。第一...

    Hibernate注解API.pdf

    - **动态查询**:利用 **@NamedQuery** 定义命名查询或使用 Criteria API 和 Query API 动态构建查询条件。 #### 六、最佳实践 1. **统一编码风格**:为了保持代码的一致性和可读性,建议团队内部统一使用一致的...

    hibernate教程

    - **查询**:`@NamedQuery`、`@NamedNativeQuery`。 #### 五、通过XML覆写元数据 虽然本文档主要讲解了注解式开发,但有时也需要通过XML文件来覆写部分元数据。这主要包括以下几个方面: - **全局级别的元数据**...

    hibernate_reference_anotation 3.5.0-final pdf

    - **命名查询**:使用 `@NamedQuery` 注解定义命名查询,便于代码中调用。 - **原生 SQL 查询映射**:使用 `@NamedNativeQuery` 定义原生 SQL 查询,通过 `@SqlResultSetMapping` 注解映射查询结果。 #### 五、元...

    Hibernate 中文 html 帮助文档

    外置命名查询(Externalizing named queries) 10.4.2. 过滤集合 10.4.3. 条件查询(Criteria queries) 10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除...

    hibernate 入门经典实例

    #### 实验十三:Query-namedQuery **实验目的:** - 理解并使用`namedQuery`功能。 **实验步骤:** - 定义一个命名查询并在`SessionFactory`中注册它,然后使用`Session`的`getNamedQuery`方法执行查询。 #### ...

Global site tag (gtag.js) - Google Analytics