Spring 使用数据库(数据库交互处置)

Spring 使用数据库(数据库交互处理)
Spring里的数据处理多数采用“模板方法”模式

针对不同的对象/关系映射框架提供的模板有JdbcTemplate、HibernateTemplate、SimpleJdbcTemplate等很多模板。

使用模板的两种方法:
1)、将其配置为Spring上下文里的Bean,然后将其织入到程序的DAO。
2)、使用Spring的DAO支持类进一步简化程序DAO。【DAO支持类派生出自己的DAO类:在编写自己的DAO实现时,可以继承DAO支持类,然后调用模板获取方法来直接访问底层的数据访问模板。例如程序DAO继承了JdbcDaoSupport,那么只需调用getJdbcTemplate()方法就可以获得一个JdbcTemplate来使用。另外每个DAO支持类都能访问它与数据库进行通信所有的类,例如JdbcDAOSupport.getConnection()获得链接。DAO支持类举例:JdbcDAOSupport、HibernateDAOSupport、simpleJdbcDAOSupport等】

Spring的大多数持久支持选项依赖于数据源,首先需要配置Spring数据源,无论什么DAO支持类,都需先陪这个。

数据源获得的几种途径(Spring里配数据源的途径):
1)、jdbc驱动程序定义的数据源;
2)、jndi查询的数据源;
3)、连接池的数据源;

下面是采用连接池的方式配置数据源,首先配置连接池,需要下载DBCP,然后把jar文件放到classPath下,DBCP里面有多个提供池功能的数据源,我们采用最常用的一个BasicDataSource,这个使用起来比较简单,BasicDataSource的配置代码和常用的配置属性见P110。

jdbc驱动定义的数据源有两种:DriverManagerDataSource、SingleConnectionDataSource,这两种都有弊端,一般不用(一个是没有进行池管理,一个是只有一个连接,用的很少)。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面首先讲解第一部分内容:使用JDBC模板

对于JDBC来说,Spring提供了3个模板类:JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate。
下面是这3个类最基本的类似的使用方式(它们的使用方式非常类似,只是执行查询、修改等操作时参数不同,配置完全类似):
1、首先声明Template:
<bean id="jdbcTemplate" class="org.spring......JdbcTemplate">
   <property name="datasource" ref="dataSource"/>
</bean>
2、然后在Dao里面声明private JdbcTemplate jdbcTemplate,并声明set方法。
3、声明Dao Bean,并注入jdbcTemplate属性:
<bean id="rantDao" class="com.roadrant......JdbcRantDao">
   <property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
4、接下来就可以在DAO中使用jdbcTemplate操作数据库了。具体使用方式参考书上使用范例。(书上都有,要详细查看其中比如更新、查询、删除等对应方法)。

注意:上面是JdbcTemplate的大体使用示例及配置,另外两个NamedParameterJdbcTemplate、SimpleJdbcTemplate的配置基本相同,只需将类名修改下并且DAO是声明变量时将变量类型修改下即可。具体的操作SQL语句方式示例自己详细看书。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面讲解第二部分内容:Spring对JDBC的DAO支持类:

Spring的JdbcDaoSupport就是用于编写基于JDBC的DAO类的基类,我们只需让自己的DAO类继承它即可(下面是使用步骤):
1、让自己的DAO类继承JdbcDaoSupport,例如
public class JdbcRantDao extends JdbcDaoSupport......{.......}
2、接下来声明自己的DAO,并注入jdbcTemplate(不需要DAO里面定义jdbcTemplate属性)或直接将数据源注入(更简单,这样就不需要在Spring里声明jdbcTemplate Bean了)
<bean id="rantDao" class="com.roadrantz......JdbcRantDao">
   <property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
【注:这样的话就不需要在自己的DAO里定义jdbcTemplate这个属性了,因为JdbcDaoSupport类里有这个属性,继承过来即可。但还需要在Spring里声明jdbcTemplate Bean】;



<bean id="rantDao" class="com.roadrantz......JdbcRantDao">
   <property name="dataSource" ref="dataSource"/>
</bean>
【注:当JdbcDao的dataSource属性被设置后,它会在内部创建一个JdbcTemplate实例,这样我们就不需要自己再Spring里明确声明一个JdbcTemplate Bean了,并且自己的Dao类里也不需要定义JdbcTemplate属性了。这种使用方式比较简单实用】

3、利用JdbcDaoSupport的getJdbcTemplate()方法能方便的访问JdbcTemplate,然后用它操作SQL语句操作数据库。具体JdbcTemplate操作SQL语句及各种增删改查操作示例见书上。

注意:上面是Spring对Jdbc的Dao支持类,使用示例及配置,另外两个NamedParameterJdbcDaoSupport、SimpleJdbcDaoSupport的配置基本相同,只需将Dao继承的类名修改下即可,例如getNamedParameterJdbcTemplate()方法即可获得NamedParameterJdbcTemplate的一个实例。具体操作SQL的使用方式将书上。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面讲解第三部分内容:Spring对ORM框架的支持,重点讲解Spring里继承Hibernate:

选择Hibernate版本:Hibernate2和Hibernate3使用中最重要一点区别是Hibernate3支持注解,Hibernate2不支持。大部分情况下还是使用Hibernate3。

与Hibernate进行狡猾的主要接口是org.hibernat.session,这个session接口提供了基本的数据访问功能,比如从数据库保存、更新、和加载对象,通过它,程序能执行任何持久功能。获得Hibernate Session对象引用的标准方式是实现Hibernate的SessionFactory接口。SessionFactory负责打开、关闭、和管理Hibernate Session,以及其他一些功能。

就像JdbcTemplate把JDBC的繁琐工作抽离出去一样,Spring的HibernateTemplate在Hibernate   Session之上提供了一个抽象层,其主要功能是简化打开和关闭Hibernate会话,并且把Hibernate的特定异常转化为表Spring ORM异常之一。

下面是Spring集成Hibernate的步骤:
1、声明hibernateTemplate Bean并注入sessionFactory:
<class id="hibernateTemplate" class="org.springframework.......HibernateTemplate">
   <property name="sessionFactory" ref="sessionFactory"/>
</class>
2、声明SessionFactory Bean,sessionFactory属性被设置为org.hibernate.SessionFactory实现的一个引用,这里提供几种可选的声明方式:
  1)、使用Spring的LocalSessionFactoryBean:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalLocalSessionFactoryBean">
   <property name="dataSource" ref="dataSource"/>
   <property name="mappingResources"><!--映射文件-->
      <list>
         <value>com/roadrantz/domain/Rant.hbm.xml</value>
         .................
      </list>
   <property/>
   <property name="hibernateProperties"><!--hibernate配置属性-->
      <props>
         <prop key="hibernate.dialect">${hibernate.dialect}</prop>
      </props>
   </property>
</bean>
  2)、我们可以选择使用注解把持久元数据标记到域对象。对于基于注解的Hibernate来说,Spring的AnnotationSessionFactory和上面的LocalSessionFactory Bean很像,只是它基于一个或多个域类里的注解和创建SessionFactory:
<bean id="sessionFactory" class=".............AnnotationSessionFactory">
   <property name="dataSource" ....../>
   <property name="annotatedClasses"><!--包含一个或多个包含持久注解的类-->
      <list>
         <value>com.roadrantz.domain.Rant</value>
         ..............
      </list>
   </property>
   <property name="hibernateProperties">......</property>
</bean>

3、然后在自己的Dao类里面定义属性,例如:
private HibernateTemplate hibernateTemplate;并定义此属性的set方法。
4、声明Dao Bean,并注入hibernateTemplate属性:
<bean id="rantDao" class="com.roadrantz........HibernateRantDao">
   <property name="hibernateTemplate" ref="hibernateTemplate">
</bean>
5、接下来就是使用hibernateTemplate操作数据库了,详细操作方式看书,。
例如:hibernateTemplate.saveOrUpdate(velicle);

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面讲解第四部分内容:Spring对Hibernate的DAO支持类:

为了让上面讲解的一部分的事情简单一些,Spring提供了HibernateDaoSupport,它能够让我们把会话工厂Bean直接装配到DAO类,会创建一个HibernateTemplate供DAO使用。

下面是使用步骤:
1、让自己的Dao类继承HibernateDaoSupport。例如:
public clss HibernateRantDao extends HibernateDaoSupport{....................}
2、在Dao里面使用getHibernteTemplate()方法获得由HibernateDaoSupport创建的HibernateTemplate(在Dao里面不需要自己定义HibernateTemplate属性了),并用它来操纵数据库。
例如:
public void saveMotorist(Motorist motorist) {
   getHibernateTemplate().saveOrUpdate(motorist);
}
3、声明Dao Bean,并把SessionFactory Bean装配到Dao Bean的SessionFactory属性:
<bean id="rantDao" class="com.roadrantz.dao.hibernate.HibernateRantDao">
   <property name="sessionFactory" ref="sessionFactory"/>
</bean>
【HibernateRantdao的新父类HibernateDaoSupport需要一个Hibernate SessionFactory,这样它才能在内部生成一个HibernateTemplate,所以需要把sessionFactory Bean注入到里面】

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面讲解第五部分内容:Hibernate3上下文会话(解决Hibernate与Spring的耦合问题):

HibernateTemplate的缺点是具有一定的侵入性,当我们使用Spring的HibernateTemplate时(无论直接使用还是通过HibernateDaoSupport),HibernateRantDao类都被耦合到Spring API,而Hibernate3的上下文会话可以解决这一问题。
下面是Hibernate3的上下文会话使用方式:
1、在自己的Dao里面定义SessionFactory sessionFactory属性,并定义此属性set方法。
2、配置自己的Dao Bean,并注入sessionFactory属性:
<bean id="rantDao" class="com.roadrantz.......HibernateRantDao">
   <property name="sessionFactory" ref="sessionFactory"/>
</bean>
【在这个新的HibernateRantDao里,sessionFactory属性注入了一个sessionFactory引用,由于sessionFactory来自于Hibernate API,所以HibernateRantDao不再依赖于Spring框架,现在我们就要使用sessionFactory来处理当前会话,而不是使用HibernateTemplate来执行持久操作。】
3、使用SessionFactory来处理当前会话:
public void saveRant(Rant rant) {
   sessionFactory.getCurrantSession().saveOrUpdate(rant);
}