在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("<span style="color: #ff0000;">com.xigua.domain.User.getUserByName</span>");
- query.setParameter("name", name);
- return query.list();
- }catch(Exception e) {
- e.printStackTrace();
- } finally {
- if(session != null) {
- session.close();
- }
- }
- return null;
- }
- }