浅谈Spring + Hibernate在持久层的Session应用

浅谈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;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

/**
 * 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}.
 
*/

public class HibernateSessionFactory {

    
/** 
     * 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";

    
/** Holds a single instance of Session */
    
private static final ThreadLocal threadLocal = new ThreadLocal();

    
/** The single instance of hibernate configuration */
    
private static final Configuration cfg = new Configuration();

    
/** The single instance of hibernate SessionFactory */
    
private static org.hibernate.SessionFactory sessionFactory;

    
/**
     * Returns the ThreadLocal Session instance.  Lazy initialize
     * the <code>SessionFactory</code> if needed.
     *
     *  
@return Session
     *  
@throws HibernateException
     
*/

    
public static Session currentSession() throws HibernateException {
        Session session 
= (Session) threadLocal.get();
        
if (session == null{
            
if (sessionFactory == null{
                
try {
                    cfg.configure(CONFIG_FILE_LOCATION);
                    sessionFactory 
= cfg.buildSessionFactory();
                }

                
catch (Exception e) {
                    System.err.println(
"%%%% Error Creating SessionFactory %%%%");
                    e.printStackTrace();
                }

            }

            session 
= sessionFactory.openSession();
            threadLocal.set(session);
        }

        
return session;
    }


    
/**
     *  Close the single hibernate session instance.
     *
     *  
@throws HibernateException
     
*/

    
public static void closeSession() throws HibernateException {
        Session session 
= (Session) threadLocal.get();
        threadLocal.set(
null);

        
if (session != null{
            session.close();
        }

    }

    
/**
     * Default constructor.
     
*/

    
private HibernateSessionFactory() {
    }

}

而我们在使用的时候则是

 

/**
 * HibernateSample
 
*/

package com.fhway.hibernate.service;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.fhway.hibernate.HibernateSessionFactory;
import com.fhway.hibernate.bean.Room;
import com.fhway.hibernate.bean.User;

/**
 * 
@author fhwei
 * 2006-9-24   下午04:28:17
 
*/

public class UserToRoomImpl  implements IUserToRoom{

    
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();

        
return false;
        
    }

    
public void selectUser(){
        Session session 
= HibernateSessionFactory.getCurrentSession();
        Transaction tx 
= session.beginTransaction();
        User user 
= (User) session.load(User.classnew Integer(1));
        System.out.println(user.getName());
        System.out.println(user.getRoom().getAddress());

        tx.commit();
        session.close();
        
    }


}

HibernateSessionFactory提供的session中我们可以操作任何我们关心的GUID对象,还可以通过
tx = session.beginTransaction();
session.save(admin);
tx.commit();

对事务进行处理

 以下是其中的一种,数据库连接和Hibernate.hbm.xml参数在Spring中配置

1.1 当我们采用向导”Add Sping Capabilities.”时会生成一个applicationContext.xmlSpringHibernate的配置文件 里面有一段代码如下:

……..    
<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>

    
<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>
进行指定目录的集中管理
 
好了对于数据库部分的配置问题就谈到这里;
 

2. 使用Spring进行管理

2.Spring对于封装HibernateTemplate的应用
2.1 HibernateDaoSupport类的应用
看下面一个类的应用
UserDao.java
package com.fhway.hibernate.dao;

import java.util.List;
import com.fhway.hibernate.bean.User;
/**
 * 
@author fhwei
 * 2006-9-27   下午11:56:05
 
*/

public interface UserDao {

    
public List findUser(User user);
    
public void saveUser(User user);

}


UserDaoHibernate.java
/**
 * HibernateSample
 
*/

package com.fhway.hibernate.dao;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.fhway.hibernate.bean.User;

/**
 * 
@author fhwei
 * 2006-9-27   下午09:23:40
 
*/

public class UserDaoHibernate extends HibernateDaoSupport implements UserDao{

    
private static final Log log = LogFactory.getLog(UserDaoHibernate.class);
    
/* findUser */
    
public List findUser(User user)
    
{
        String hql 
= " from User as user where  user.name = '"+ user.getName() +"";
        
return getHibernateTemplate().find(hql);
    }

    
/* saveUser */
    
public void saveUser(User user)
    
{
        getHibernateTemplate().save(user);
    }

}

 
对于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语句一样的使用
public List findUserById(String id) {
return hibernateTemplate.find("from User user " +
"where user.id = ?",    
id, Hibernate.STRING);
}


 

 

呵呵,现在就分析结束了,其实还是挺有趣的
 

本文参考了<Spring in action >中相应内容,说得不对得地方欢迎指正!

 

 

 

 

posted @ 2006-09-30 16:53  fhway  阅读(247)  评论(0)    收藏  举报