做了四年的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;
}
}
|
|