DataSourcespring
標準化的取得鏈接的方式sql
spring鏈接池 express
dbcp配置apache
Hibernate使用Annotation的方式設計模式
簡單整合session
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="annotatedClasses"> <list> <value>com.bjsxt.model.User</value>
<value>com.bjsxt.model.Log</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>
sessionFactory的class並非hibernate本身的,而是使用的Spring的AnnotationSessionFactoryBeanapp
它裏面有不少的屬性:性能
他須要注入的信息有:(也就是這個類中含有的set方法)url
1. dataSource 數據源spa
2. annotateClasses
它須要注入的信息是一個集合,表示哪些實體類上加了註解,須要用到hibernate
3. hibernateProperties
這是一個Properties類型的對象,表示Hibernate的一些屬性,好比Hibernate方言等。
上面的例子中是用的注入 annotateClasses這個屬性,可是若是類很是多,這個就很是不方便了
咱們能夠注入 packagesToScan這個屬性
<property name="packagesToScan"> <list> <value>com.bjabc.model</value> </list> </property>
而後再在須要的實體類上加上Hibernate須要的註解便可,好比@Entity之類的
這種方式是Annotation的方式,不須要hibernate的配置文件
若是使用xml方式 class="org.springframework.orm.hibernate3.annotation.SessionFactoryBean
並且還有加入一個name = mappingResources value=....hbm.xml的子屬性,表示hibernate的配置文件
事務管理
首先要搞清事務的開始和結束
有兩種管理方式
先說說Annotation
首先要在spring的bean.xml中引入annotation驅動
而後把sessionFactory交給事務的txManager管理
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven transaction-manager="txManager"/>
接下來就是配置須要添加事務管理的類了
好比是加在管理層上
@Transactional(readOnly = true) public class UserServiceImpl implements UserService { public Foo getFoo(String name) { // do something } @Transactional(propagation = Propagation.REQUIRED) public void add(User user) { userDAO.save(user);
} }
那麼對於DAO層
public class UserDAOimpl implements UserDAO { private SessionFactory sessionFactory; public void save(User user) { session s = sessionFactory.getCurrentSession(); s.save(user); } }
這裏必需要getCurrentSession,就是說這個時候鏈接已經建立了,不能夠再從新create了。
類或者方法上上只須要加入@Transactional 就能夠了
可是有不少屬性
最要的屬性必需要加上的 (不加也同樣,默認就是)
propagation = Propagation.REQUIRED
其餘的
readOnly = false
表示創建一個readOnly的鏈接,對於不須要增刪改只須要查的動做
有兩個好處, 1。 提升性能, 2,防止意外的修改操做
roolBackFor
默認下都是對於runtimeException
XML方式
也就是spring 的AOP方式
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="getUser" read-only="true" /> <tx:method name="add*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
定義一個切面,表示事務,而且加入到相應方法
<aop:config> <aop:pointcut id="bussinessService" expression="execution(public * com.bjsxt.service..*.*(..))" /> <aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" /> </aop:config>
而後在類上就不用加那些標記了
實際開發過程當中,用的xml方法比較多
由於不用在每一個方法上加標記
HibernateTemplate
裏面有一種設計模式:Template Method 模板方法
把對sessionFactory的管理交給hibernateTempate
spring的容器裏
<bean id="sessionFactory"> ... </bean> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean>
看一下HibernateTempate這個類的源碼,能夠看到裏面有幾個屬性,須要注入
好比有一個setSessionFactory()方法
而這個類也已經把sessionFactory裏的不少方法都封裝好了
好比load()方法,save()方法等。
因此在程序裏直接調用這些方法就好了
那麼在UserDAOimpl裏面
就不須要像之前那樣有一個sessionFactory對象了
只須要有一個HibernateTemplate對象就能夠了,而後經過注入得到這個對象
而後調用這個對象的save()方法等等。
那麼它內部的原理是什麼呢?
能夠看一下 hibernateTemplate.save方法的源碼
這個方法的實現過程能夠這麼理解
所謂模板方法,其實就是說咱們以前用sessionFactory在各個DAO中創建鏈接和斷開鏈接的操做都是同樣的,因此每一個DAO的開始和結束都差很少i,因此咱們定義一個方法,他的開始和結束同樣,而後再在中間插入咱們自定義的操做就好了。
hibernate能夠封裝jdbc,jdo,orm等不少中間層的產品
可是有兩個相同的封裝過程
1. 提供特定的Template
2. 全部的異常會封裝從成DataAcessExceptin
這是一個runtime異常,會回滾
callback 回調/鉤子