刚好十一期间 Spring2.0的中文reference出来了 所以把这部分总结实践一下
一 资源管理
DataSource sessionFactory的组装
beans-config.xml
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
<!-- =================================================================== -->
<!-- JDBC dataSource -->
<!-- =================================================================== -->
<!-- ***********************************************************************
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/shtest</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>72001234</value>
</property>
</bean>
************************************************************************ -->
<!-- =================================================================== -->
<!-- c3p0 dataSource -->
<!-- =================================================================== -->
< bean id ="dataSource" class ="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method ="close" >
< property name ="driverClass" >
< value > com.mysql.jdbc.Driver </ value >
</ property >
< property name ="jdbcUrl" >
< value > jdbc:mysql://localhost:3306/shtest </ value >
</ property >
< property name ="properties" >
< props >
< prop key ="c3p0.acquire_increment" > 2 </ prop >
< prop key ="c3p0.idle_test_period" > 200 </ prop >
< prop key ="c3p0.timeout" > 1000 </ prop >
< prop key ="c3p0.max_size" > 100 </ prop >
< prop key ="hibernate.c3p0.max_statements" > 100 </ prop >
< prop key ="hibernate.c3p0.min_size" > 20 </ prop >
< prop key ="user" > root </ prop >
< prop key ="password" > 72001234 </ prop >
</ props >
</ property >
</ bean >
<!-- =================================================================== -->
<!-- Hibernate sessionFactory -->
<!-- =================================================================== -->
< bean id ="sessionFactory" class ="org.springframework.orm.hibernate3.LocalSessionFactoryBean" destroy-method ="close" >
< property name ="dataSource" >
< ref bean ="dataSource" />
</ property >
< property name ="mappingResources" >
< list >
< value > /com/ergal/hibernate/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 >
< prop key ="hibernate.current_session_context_class" > thread </ prop >
</ props >
</ property >
</ bean >
<!-- =================================================================== -->
<!-- Hibernate POJO -->
<!-- =================================================================== -->
< bean id ="userDao" class ="com.ergal.hibernate.UserDao" >
< property name ="sessionFactory" >
< ref bean ="sessionFactory" />
</ property >
</ bean >
<!-- =================================================================== -->
<!-- transactionManager -->
<!-- =================================================================== -->
< bean id ="transactionManager" class ="org.springframework.orm.hibernate3.HibernateTransactionManager" >
< property name ="sessionFactory" >
< ref bean ="sessionFactory" />
</ property >
</ bean >
<!-- =================================================================== -->
<!-- Dao Proxy -->
<!-- =================================================================== -->
< bean id ="userDaoProxy" class ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >
< property name ="transactionManager" >
< ref bean ="transactionManager" />
</ property >
< property name ="proxyInterfaces" >
< list >
< value > com.ergal.hibernate.IUserDao </ value >
</ list >
</ property >
< property name ="target" >
< ref bean ="userDao" />
</ property >
< property name ="transactionAttributes" >
< props >
< prop key ="insert" > PROPAGATION_REQUIRED </ prop >
</ props >
</ property >
</ bean >
</ beans >
也可以直接使用JNDI资源
< bean id ="myDataSource" class ="org.springframework.jndi.JndiObjectFactoryBean" >
< property name ="jndiName" value ="java:comp/env/jdbc/myds" />
</ bean >
...
</ beans >
二 HibernateTemplate
HibernateTemplate上有一些方便的方法可以自动建立callback对象 一些方法get() save() delete() 等等
在不使用代理的情况下
UserDao变的比较灵活
比如按名字查询的方法可以写成
import java.util.Iterator;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate3.HibernateTemplate;
public class UserDao implements IUserDao
... {
private HibernateTemplate hibernateTemplate;
public UserDao()...{}
/**//*
public UserDao(SessionFactory sessionFactory)
{
this.sessionFactory=sessionFactory;
}*/
public void setSessionFactory(SessionFactory sessionFactory)
...{
hibernateTemplate=new HibernateTemplate(sessionFactory);
}
public void insert(User user)
...{
hibernateTemplate.save(user);
// TODO Auto-generated method stub
/**//*Session session = sessionFactory.openSession();
Transaction tx=session.beginTransaction();
session.save(user);
tx.commit();
session.close();*/
}
public String getPassword(String username)
...{
/**//*
Session session = sessionFactory.openSession();
Transaction tx=session.beginTransaction();
List result=session.createQuery("from User u where username=:name").setString("name", username).list();
String password=null;
for(Iterator it=result.iterator(); it.hasNext();)
{
User u =(User)it.next();
Hibernate.initialize(u.getPassword());
password=(String)u.getPassword();
}
tx.commit();
session.close();
return password;
*/
List result=hibernateTemplate.find("from User u where username=?", username);
String password=null;
for(Iterator it=result.iterator(); it.hasNext();)
...{
User u =(User)it.next();
Hibernate.initialize(u.getPassword());
password=(String)u.getPassword();
}
return password;
}
}
也可以写成
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
List result = session.createQuery( " from User u where username=:name " ).setString( " name " , username).list();
String password = null ;
for (Iterator it = result.iterator(); it.hasNext();)
... {
User u =(User)it.next();
Hibernate.initialize(u.getPassword());
password=(String)u.getPassword();
}
return password;
当然 直接利用 hibernateTemplate的方法是比较简洁的
三 HibernateDaoSupport
可以省去一些SessionFactory和HibernateTemplate的管理 只需要注入SessionFactory的实例就可以了
Constructor Summary | |
---|---|
HibernateDaoSupport() |
Method Summary | |
---|---|
protected void | checkDaoConfig() Abstract subclasses must override this to check their configuration. |
protected void | closeSessionIfNecessary(org.hibernate.Session session) Deprecated. in favor of releaseSession |
protected DataAccessException | convertHibernateAccessException(org.hibernate.HibernateException ex) Convert the given HibernateException to an appropriate exception from the org.springframework.dao hierarchy. |
protected HibernateTemplate | createHibernateTemplate(org.hibernate.SessionFactory sessionFactory) Create a HibernateTemplate for the given SessionFactory. |
HibernateTemplate | getHibernateTemplate() Return the HibernateTemplate for this DAO, pre-initialized with the SessionFactory or set explicitly. |
protected org.hibernate.Session | getSession() Get a Hibernate Session, either from the current transaction or a new one. |
protected org.hibernate.Session | getSession(boolean allowCreate) Get a Hibernate Session, either from the current transaction or a new one. |
org.hibernate.SessionFactory | getSessionFactory() Return the Hibernate SessionFactory used by this DAO. |
protected void | releaseSession(org.hibernate.Session session) Close the given Hibernate Session, created via this DAO's SessionFactory, if it isn't bound to the thread. |
void | setHibernateTemplate(HibernateTemplate hibernateTemplate) Set the HibernateTemplate for this DAO explicitly, as an alternative to specifying a SessionFactory. |
void | setSessionFactory(org.hibernate.SessionFactory sessionFactory) Set the Hibernate SessionFactory to be used by this DAO. |
于是可以把代码改成以下来测试一下
import java.util.Iterator;
import java.util.List;
import org.hibernate.Hibernate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class UserDao extends HibernateDaoSupport implements IUserDao
... {
//private HibernateTemplate hibernateTemplate;
public UserDao()...{}
/**//*
public UserDao(SessionFactory sessionFactory)
{
this.sessionFactory=sessionFactory;
}*/
/**//*
public void setSessionFactory(SessionFactory sessionFactory)
{
hibernateTemplate=new HibernateTemplate(sessionFactory);
}*/
public void insert(User user)
...{
getHibernateTemplate().save(user);
// TODO Auto-generated method stub
/**//*Session session = sessionFactory.openSession();
Transaction tx=session.beginTransaction();
session.save(user);
tx.commit();
session.close();*/
}
public String getPassword(String username)
...{
/**//*
Session session = sessionFactory.openSession();
Transaction tx=session.beginTransaction();
List result=session.createQuery("from User u where username=:name").setString("name", username).list();
String password=null;
for(Iterator it=result.iterator(); it.hasNext();)
{
User u =(User)it.next();
Hibernate.initialize(u.getPassword());
password=(String)u.getPassword();
}
tx.commit();
session.close();
return password;
*/
List result=getHibernateTemplate().find("from User u where username=?", username);
String password=null;
for(Iterator it=result.iterator(); it.hasNext();)
...{
User u =(User)it.next();
password=(String)u.getPassword();
}
return password;
}
}
这样很多管理就被省去了 包括session sessionFactory
reference上还写了一些关于使用
Hibernate原生API的方法
就是直接自己编写Hibernate的实现方法来实现DAO
如
Transaction tx = session.beginTransaction();
List result = session.createQuery( " from User u where username=:name " ).setString( " name " , username).list();
String password = null ;
for (Iterator it = result.iterator(); it.hasNext();)
... {
User u =(User)it.next();
Hibernate.initialize(u.getPassword());
password=(String)u.getPassword();
}
tx.commit();
session.close();
return password;
不使用回调基于DAO的实现
无需将Hibernate访问代码放在一个回调中 只要符合Spring通用的DataAccessException异常体系HibernateDaoSupport提供了访问当前事务绑定的session对象的函数 保证在这种情况下异常的正常转化 (false)作为参数 表示是否允许创建 此时整个调用在一个session中完成(整个生命周期由事务控制 避免了关闭session的需要)
Session session = getSession(getSessionFactory, false )
try
... {
List result=session.createQuery("from User u where username=:name").setString("name", username).list();
if(result ==null)
...{
throw .....
}
return result;
}
catch (HibernateException ex)
... {
throw convetHibernateAccessException(ex);
}
编程式事务管理
自己组装业务实现的类 利用
org.springframework.transaction.support .TransactionTemplate
org.springframework.transaction.support.TransactionCallbackWithoutResult
org.springframework.orm.hibernate3.HibernateTemplate
org.springframework.transaction.TransactionStatus
org.springframework.orm.hibernate3.HibernateTransactionManager
org.springframework.transaction.TranscationDefinition这些接口和方法来进行事务管理 看起来没有那么简洁
声明式事务管理
定义一个代理类
核心部分如下
<!-- =================================================================== -->
<!-- transactionManager -->
<!-- =================================================================== -->
< bean id ="transactionManager" class ="org.springframework.orm.hibernate3.HibernateTransactionManager" >
< property name ="sessionFactory" >
< ref bean ="sessionFactory" />
</ property >
</ bean >
<!-- =================================================================== -->
<!-- Dao Proxy -->
<!-- =================================================================== -->
< bean id ="userDaoProxy" class ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >
< property name ="transactionManager" >
< ref bean ="transactionManager" />
</ property >
< property name ="proxyInterfaces" >
< list >
< value > com.ergal.hibernate.IUserDao </ value >
</ list >
</ property >
< property name ="target" >
< ref bean ="userDao" />
</ property >
< property name ="transactionAttributes" >
< props >
< prop key ="insert" > PROPAGATION_REQUIRED </ prop >
</ props >
</ property >
</ bean >