Java Hibernate持久化框架为我们做数据库存取操作带来很大的遍历,其最大的几个特点是:
1.数据库表和内存中Java对象对应,透明操作数据库。
2.不用写大量的、繁琐的、无聊的、蛋疼的、傻逼的、没有技术含量的get、set方法(jdbc)。
3.自动生成数据库语句,几乎可以跨数据库服务器平台,仅需要修改配置中数据库方言等少数几个地方即可。
等等,以上三点优点是我个人经验总结,可能还会有其他的各种优点我还没有发现。
然而,它在给我们带来便利的时候,也带来了少许不方便的地方,比如:我现在要批量删除数据库中一张表的数据,并且已经有了这些数据的主键id,在Hibernate中的做法就是先找到这些id的数据,然后遍历list,对每一个对象执行delete操作,反应的show_sql中就是执行了很多的sql语句。但是在Sql中的做法就很简单——delete from table where id in(5,2,0,1,3,1,4);完毕。
举上面的这个例子,并不是为了否定hibernate的作用,而是为了引入本博文的主题:利用hibernate执行原生sql语句,下面是项目中用到的一个HibernateHqlUtil的接口和实现。封装很简单,因为在项目中仅仅只有少量几处使用到,这个封装足矣。
HibernateHqlUtil接口类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/**
* Copyright 2013 HUST.
* Visit http://50vip.com/
* All right reserved.
*/
package
com.rule.pm.dao;
import
java.util.List;
/**
* @author Xewee.Zhiwei.Wang
* @version 2013-1-4 下午3:06:09
* @Contract wzwahl36@QQ.com or http://50vip.com/
*/
public
interface
HibernateHqlUtil {
public
List<Object[]> queryHqlBySession(String hql,
int
n);
public
<T> List<T> queryHqlBySession(String hql, T bean);
public
Object queryHqlBySession(String hql);
public
int
executeUpdate(String hql);
}
|
HibernateHqlUtilImpl接口实现类
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
|
/**
* Copyright 2013 HUST.
* Visit http://50vip.com/
* All right reserved.
*/
package
com.rule.pm.dao.impl;
import
java.util.List;
import
org.hibernate.SQLQuery;
import
org.hibernate.Session;
import
org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import
com.rule.pm.dao.HibernateHqlUtil;
/**
*
* @author Xewee.Zhiwei.Wang
* @version 2013-1-14 下午8:46:30
* @Contract wzwahl36@QQ.com or http://50vip.com/
*/
public
class
HibernateHqlUtilImpl
extends
HibernateDaoSupport
implements
HibernateHqlUtil {
/**
* 执行查询语句,返回唯一值的结果
* eg:"select min(a.employeeid) from Emplyees a;"
* eg:"select count(*) from Emplyees a;"
*/
public
Object queryHqlBySession(String sql) {
Session session =
super
.getSession();
SQLQuery query = session.createSQLQuery(sql);
Object object = query.uniqueResult();
session.close();
return
object;
}
/**
* 执行hql/sql查询语句,将数据返回到column1~n,顺序排列
* eg:"select name as column1, sex as column2 from Emplyees a;"
*/
@SuppressWarnings
(
"unchecked"
)
public
List<Object[]> queryHqlBySession(String sql,
int
n) {
Session session =
super
.getSession();
SQLQuery query = session.createSQLQuery(sql);
for
(
int
i =
1
; i <= n; i++) {
query.addScalar(
"column"
+ i);
}
return
query.list();
}
/**
* 执行hql/sql查询语句,将数据返回bean中,bean的name和sql中as的name相同,自动注入
*/
@SuppressWarnings
(
"unchecked"
)
public
<T> List<T> queryHqlBySession(String sql, T bean) {
Session session =
super
.getSession();
SQLQuery query = session.createSQLQuery(sql).addEntity(bean.getClass());
List<T> result = query.list();
session.close();
return
result;
}
/**
* 执行hql/sql更新语句(delete,update),返回受影响的数据条数
* eg:"delete from Emplyees a where a.id<10;"
*/
public
int
executeUpdate(String sql) {
Session session =
super
.getSession();
SQLQuery query = session.createSQLQuery(sql);
int
count = query.executeUpdate();
session.close();
return
count;
}
}
|
需要注意的是:虽然我在项目中做了,但是如果用到Hibernate,就最好不要在系统中使用sql语句,因为使用Hibernate的优点之一就是利用它开发的系统几乎可以跨数据库服务器平台(本博文前面三点总结中的第三点)。如果在系统中执行较为复杂,具有平台性的sql语句,例如:limit关键字、top关键字等,将会失去hibernate的这个优势。当然如果你执行的sql语句不具有平台型,而是采用标准的sql语句,这个就没啥影响了。不过少量使用,即使换数据库,我修改那部分sql代码就行了,工作量也不大。