浅谈Spring + Hibernate在持久层的Session应用
开发环境: Eclipse3.2 + MyEclipse + MySQL5.0
使用的框架为Hibernate3.0 ;Spring1.2
1. 首先谈谈独立使用Hibernate的Session管理
一般的我们会先建一个Java的Project 然后利用MyEclipse在项目里面建立一个由向导”Add Hibernate Capabilities….”产生的HibernateSessionFactory类 文档如下:
package
com.fhway.hibernate;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.hibernate.HibernateException;
import
org.hibernate.Session;
import
org.hibernate.cfg.Configuration;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* Configures and provides access to Hibernate sessions, tied to the
* current thread of execution. Follows the Thread Local Session
* pattern, see {@link http://hibernate.org/42.html}.
*/
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
HibernateSessionFactory
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* Location of hibernate.cfg.xml file.
* NOTICE: Location should be on the classpath as Hibernate uses
* #resourceAsStream style lookup for its configuration file. That
* is place the config file in a Java package - the default location
* is the default Java package.<br><br>
* Examples: <br>
* <code>CONFIG_FILE_LOCATION = "/hibernate.conf.xml".
* CONFIG_FILE_LOCATION = "/com/foo/bar/myhiberstuff.conf.xml".</code>
*/
private static String CONFIG_FILE_LOCATION = "/com/aflyer/hibernate/hibernate.cfg.xml";
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//** Holds a single instance of Session */
private static final ThreadLocal threadLocal = new ThreadLocal();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//** The single instance of hibernate configuration */
private static final Configuration cfg = new Configuration();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//** The single instance of hibernate SessionFactory */
private static org.hibernate.SessionFactory sessionFactory;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* Returns the ThreadLocal Session instance. Lazy initialize
* the <code>SessionFactory</code> if needed.
*
* @return Session
* @throws HibernateException
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static Session currentSession() throws HibernateException ...{
Session session = (Session) threadLocal.get();
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (session == null) ...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (sessionFactory == null) ...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try ...{
cfg.configure(CONFIG_FILE_LOCATION);
sessionFactory = cfg.buildSessionFactory();
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
catch (Exception e) ...{
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static void closeSession() throws HibernateException ...{
Session session = (Session) threadLocal.get();
threadLocal.set(null);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (session != null) ...{
session.close();
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* Default constructor.
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private HibernateSessionFactory() ...{
}
}
而我们在使用的时候则是
/** */
/**
* HibernateSample
*/
package
com.fhway.hibernate.service;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.hibernate.Session;
import
org.hibernate.Transaction;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
com.fhway.hibernate.HibernateSessionFactory;
import
com.fhway.hibernate.bean.Room;
import
com.fhway.hibernate.bean.User;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* @author fhwei
* 2006-9-24 下午04:28:17
*/
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
UserToRoomImpl
implements
IUserToRoom
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public boolean ManyToOne()...{
Room room1 = new Room();
room1.setAddress("NTU-M8-419");
Room room2 = new Room();
room2.setAddress("NTU-G3-302");
User user1 = new User();
user1.setName("bush");
user1.setRoom(room1);
User user2 = new User();
user2.setName("caterpillar");
user2.setRoom(room1);
User user3 = new User();
user3.setName("momor");
user3.setRoom(room2);
Session session = HibernateSessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
session.save(user1); // 主控方操作,被控方也会对应操作
session.save(user2);
session.save(user3);
tx.commit();
session.close();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return false;
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void selectUser()...{
Session session = HibernateSessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
User user = (User) session.load(User.class, new Integer(1));
System.out.println(user.getName());
System.out.println(user.getRoom().getAddress());
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
tx.commit();
session.close();
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
在
HibernateSessionFactory
提供的
session
中我们可以操作任何我们关心的
GUID
对象
,
还可以通过
tx =
session
.beginTransaction();
session
.save(admin);
tx
.commit();
对事务进行处理
以下是其中的一种,数据库连接和Hibernate的.hbm.xml参数在Spring中配置
1.1 当我们采用向导”Add Sping Capabilities….”时会生成一个applicationContext.xml的Spring和Hibernate的配置文件 里面有一段代码如下:
……..
<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>
file:src/com/fhway/hibernate/hibernate.cfg.xml
</value>
</property>
</bean>
.....
在这里
,
实际上
Spring
仍然利用了
Hibernate
自身的配置文件处理联接问题
,
以下再谈一下他们的配置引用
session
配置参数的几种方法
<
bean id
=
"
dataSource
"
class
=
"
org.apache.commons.dbcp.BasicDataSource
"
destroy
-
method
=
"
close
"
>
<
property name
=
"
driverClassName
"
>
<
value
>
com.mysql.jdbc.Driver
</
value
>
</
property
>
<
property name
=
"
url
"
>
<
value
>
jdbc:mysql:
//
localhost:3306/hibernatedb</value>
</
property
>
<
property name
=
"
username
"
>
<
value
>
root
</
value
>
</
property
>
<
property name
=
"
password
"
>
<
value
>
admin
</
value
>
</
property
>
</
bean
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
bean id
=
"
sessionFactory
"
class
=
"
org.springframework.orm.hibernate3.LocalSessionFactoryBean
"
>
<
property name
=
"
dataSource
"
>
<
ref local
=
"
dataSource
"
/>
</
property
>
<
property name
=
"
mappingResources
"
>
<
list
>
<
value
>
com
/
fhway
/
hibernate
/
bean
/
Room.hbm.xml
</
value
>
<
value
>
com
/
fhway
/
hibernate
/
bean
/
User.hbm.xml
</
value
>
</
list
>
</
property
>
<
property name
=
"
hibernateProperties
"
>
<
props
>
<
prop key
=
"
hibernate.dialect
"
>
org.hibernate.dialect.MySQLDialect
</
prop
>
<
prop key
=
"
hibernate.show_sql
"
>
true
</
prop
>
</
props
>
</
property
>
</
bean
>
当然你可以在
dataSource
的
bean
中利用
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/myDatasource</value>
</property>
</bean>
来代替
org.apache.commons.dbcp.BasicDataSource
类
还可以这样
<bean id="sessionFactory" class="org.springframework.
orm.hibernate3.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.
dialect.MySQLDialect</prop>
</props>
</property>
…
</bean>
利用
hibernate
的
Properties
文件
对于
mappingResources
文件可以利用
<bean id="sessionFactory" class="org.springframework.
orm3.hibernate.LocalSessionFactoryBean">
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/com/fhway/hibernate/model</value>
</list>
</property>
…
</bean>
进行指定目录的集中管理
好了对于数据库部分的配置问题就谈到这里;
对于DB 的操作我们只要继承了Spring提供的对Hibernate的封装类
HibernateDaoSupport
就可以轻松的通过
getHibernateTemplate()
取得
Session.
2.2hibernateTemplate的使用
<
bean id
=
"
hibernateTemplate
"
class
=
"
org.springframework.orm3.hibernate.HibernateTemplate
"
>
<
property name
=
"
sessionFactory
"
>
<
ref bean
=
"
sessionFactory
"
/>
</
property
>
</
bean
>
然后把bean hibernateTemplate注入到你要使用的每个Dao中
使用的时候为
<
bean id
=
"
studentDao
"
class
=
"
com.fhway.hibernate.dao.hibernate.updateUserDao
"
>
<
property name
=
"
hibernateTemplate
"
>
<
ref bean
=
"
hibernateTemplate
"
/>
</
property
>
</
bean
>
public
void
updateUserDao (User user)
...
{
hibernateTemplate.update(user);
}
HQL语句一样的使用
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
List findUserById(String id)
...
{
return hibernateTemplate.find("from User user " +
"where user.id = ?",
id, Hibernate.STRING);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
呵呵,现在就分析结束了,其实还是挺有趣的
本文参考了<Spring in action >中相应内容,说得不对得地方欢迎指正!