Spring的数据库支持

第一章    Spring 的数据库支持
5.1 Spring DAO 的支持
Spring 提供的 DAO( 数据访问对象 ) 支持主要的目的是便于以标准的方式使用不同的数据访问技术, JDBC Hibernate 或者 JDO 等。它不仅可以让你方便地在这些持久化技术间切换, 而且让你在编码的时候不用考虑处理各种技术中特定的异常。
1)  一致的异常层次
Spring 提供了一种方便的方法,把特定于某种技术的异常,如SQLException, 转化为自己的异常,这种异常属于以DataAccessException 为根的异常层次。这些异常封装了原始异常对象,这样就不会有丢失任何错误信息的风险。
除了对JDBC异常的封装,Spring也对Hibernate异常进行了封装,把它们从一种专有的checked异常 (Hibernate3.0以前的版本),转化为一系列抽象的运行时异常。对JDO也是这样。 它可以让你轻松处理大多数持久化异常(这些异常大多是不可恢复的,而且只出现在特定 的层次),而不再需要讨厌的样板式catch/throw代码块和异常声明。你仍然可以在需要 的地方捕获并处理这些异常。就像我们上面提到的,JDBC异常(包括特定于某种数据库 方言的异常)也可以被转化为同样的异常层次,这意味着你可以在一致的编程模型下,通 过JDBC来执行某些操作。
上述情况适用于各种使用模板方式的ORM访问框架。如果使用拦截器方式,你在应用中 就得自己小心处理HibernateException JDOException等,最好是委托给 SessionFactoryUtils convertHibernateAccessException convertJdoAccessException等方法。这些方法可以把相应的异常转 化为与org.springframework.dao中定义的异常层次相兼容的异常。其中JDOExceptionunchecked异常,它们则被简单地抛出,尽管这在异常处理方面牺牲了通用的DAO抽象。
2) 一致的 DAO 支持抽象类
为了便于以一种一致的方式使用各种数据访问技术,如 JDBC JDO Hibernate Spring 提供了一套抽象 DAO 类供你扩展。这些抽象类提供了一些方法,通过它们你可以 获得与你当前使用的数据访问技术相关的数据源和其他配置信息。
Dao 支持类:
JdbcDaoSupport - JDBC 数据访问对象的基类。 需要一个 DataSource ,同时为子类提供 JdbcTemplate
HibernateDaoSupport - Hibernate 数据访问对象的基类。 需要一个 SessionFactory ,同时为子类提供 HibernateTemplate 。也可以选择直接通过 提供一个 HibernateTemplate 来初始化, 这样就可以重用后者的设置,例如 SessionFactory flush 模式,异常翻译器( exception translator )等等。
5.2 Spring 中使用JDBC
Java 开发人员都有过直接使用 JDBC 编写数据库程序的经历,由于 JDBC API 过于底层,开发人员不但需要编写数据操作代码,还需要编写获取 JDBC 链接、处理异常、释放资源等代码。即使是一个再简单不孤傲的数据库操作,也需要至少几十行的代码。 Spring JDBC 通过模板和回调机制大大降低了使用 JDBC 的复杂度 , 借由 JdbcTemplate 的帮助,我们仅需要编写那些“必不可少”的代码就可以进行数据库操作了。
1) 简单的 JdbcTemplate
代码清单 1
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
public class JdbcDAO {
    public static void main(String[] args) {
       DriverManagerDataSource ds = new DriverManagerDataSource();
       ds.setDriverClassName( "net.sourceforge.jtds.jdbc.Driver" );
       ds.setUrl( "jdbc:jtds:Sqlserver://10.0.160.188:1433/WPE" );
       ds.setUsername( "sa" );
       ds.setPassword( "sa" );
       JdbcTemplate jdbcTemplate = new JdbcTemplate();
       jdbcTemplate.setDataSource(ds);
       String sql = "create table T_USER(U_ID int primary key ,U_NAME varchar(20))" ;
       jdbcTemplate.execute(sql);
    }
}
代码清单 1 中我们创建了一个 DriverManagerDataSource 数据源对象,又创建了一个 JdbcTemplate 对象通过调用 JdbcTemplate 对象的 execute 方法向数据库中创建一个表。很简单的一个例子但是我们已经感受到 JdbcTemplate 的力量。
    2) 使用 JdbcDaoSupport
       我们看到代码清单中的 JdbcTemplate 访问数据库是那么的简单,但是 Spring 还进一步简化了模板类的支持类, JdbcDaoSupport 本身包含了一个 JdbcTemplate 类实例变量,并开放了设置 dataSource 的接口,这样我们仅需要简单地扩展 JdbcDaoSupport 就可以定以自己的 DAO 类了。
代码清单 2
<!-- 定义 dataSource -->
< bean id = "dataSource" class = "net.sourceforge.jtds.jdbc.Driver" >
    < property name = "driverClassName"
              value = "net.sourceforge.jtds.jdbc.Driver" />
    < property name = "url"
value = "jdbc:jtds:Sqlserver://10.0.160.188:1433/WPE" />
    < property name = "username" value = "sa" />
    < property name = "password" value = "sa" />
</ bean >
<!-- 定义 jdbcTemplate -->
< bean id = "jdbcTemplate"
           class = "org.springframework.jdbc.core.JdbcTemplate" >
    < property name = "dateSource" ref = "dataSource" />
</ bean >
<!-- 定义 dao 抽象父类用于其它类使用 -->
< bean id = "dao" abstract = "true" >
    < property name = "jdbcTemplate" ref = "jdbcTemplate" />
</ bean >
< bean id = "jdbcDAO" class = "com.tony.test.JdbcDAO" parent = "dao" />
 
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class JdbcDAO extends JdbcDaoSupport{
    public void save(String name) { // 向数据库中插入一条记录
       String sql = "INSERT INTO T_USER(U_NAME) VALUES(?)" ;
       this .getJdbcTemplate() .update(sql, new Object[]{name});
    }
}
代码清单 2 中我们通过 Spring 的配置文件将 JdbcDAO 装配完成 , 我们就可以通过 this .getJdbcTemplate() 获得 JdbcTemplate 对象直接操作数据库。除了标准的 JdbcTemplate 以外,在 Spring2.0 中新增了 NamedParameterJdbcDaoSupport 以提供明明参数绑定的功能。
3)NamedParameterJdbcDaoSupport
在低版本的 Spring , 用户只能使用 ? 占位符声明参数,并使用索引号绑定参数,使用这种方法绑定参数时,必须足够小心,以保证参数的索引号和 SQL 语句中占位符(?)的位置正确匹配。这种编程模式被认为是弱稳定的,因为当新增一个?占位符时,可能导致原来所有的参数绑定方法都需要因此调整索引号,这极有可能引入一些不容易发现的错误。 Spring2.0 提供了新的支持命名参数绑定的 NamedParameterJdbcDaoSupport 模板类,来一起看看下面的代码
代码清单 3
import org.springframework.jdbc.core.namedparam.
NamedParameterJdbcDaoSupport;
public class JdbcDAO extends NamedParameterJdbcDaoSupport{
    public void save(String name) {
       Map<String,String> value = new HashMap<String,String>();
       value.put( "U_NAME" , name); // 定义了一个 Map, name put Map
       String sql = "INSERT INTO T_USER(U_NAME) VALUES(:U_NAME)" ;
       // 调用 this .getNamedParameterJdbcTemplate() 对数据库操作
this .getNamedParameterJdbcTemplate().update(sql,value);
    }
}
    在代码清单中我们看到使用 NamedParameterJdbcTemplate 的方法更加灵活,并且 SQL 语句也更加清晰。
5.3 Spring ORM 框架支持
Spring 在资源管理, DAO 实现支持以及事务策略等方面提供了与 Hibernate JDO Oracle TopLink iBATIS SQL Mappings 以及 JPA 的集成。以 Hibernate 为例, Spring 通过使用许多 IoC 的便捷特性对它提供了一流的支持,帮助我们处理很多典型的 Hibernate 整合的问题。所有的这些支持,都遵循 Spring 通用的事务和 DAO 异常体系。通常来说有两种不同的整合风格:我们可以使用 Spring 提供的 DAO 模板,或者直接使用 Hibernate/JDO/TopLink 等工具的原生 API 编写 DAO 。无论采取哪种风格,这些 DAO 都可以通过 IoC 进行配置,并参与到 Spring 的资源和事务管理中去。
使用 Spring 构建 O/R Mapping DAO 的好处包括:
1)      测试简单。 Spring IoC 使得替换不同的实现和配置变得非常简单,这些内容包括: Hibernate SessionFactory 的位置, JDBC DataSource ,事务管理器以及映射对象的实现(如果需要)等。这样也就很容易隔离并测试持久化相关的代码的各个部分。
2)      异常封装。 Spring 能够封装你所选择的O/R Mapping工具所抛出的异常,将它们从专有的、潜在的checked exception转化为一组抽象的runtime DataAccessException体系。这可以使你仅需要在恰当的应用程序层次去处理大部分不可恢复的持久层异常,从而避免了很多令人讨厌的catch/throw以及异常声明。当然,你还是可以在你需要的地方捕捉和处理异常。回想一下JDBC异常(包括与DB相关的Dialect)被转变为同样的异常体系,这就意味着你可以在一致的编程模型中处理JDBC操作。
3)      通用的资源管理。 Spring application context 能够处理诸如 Hibernate SessionFactory JDBC DataSource iBatis SQL Maps 配置对象以及其他相关资源的定位和配置。这样,这些配置的值很容易被管理和修改。 Spring 提供了简单、有效、安全的对持久层资源的处理。以 Hibernate 为例,通常在使用 Hibernate 时,需要使用同一个 Hibernate Session 对象以确保高效和恰当地事务处理。 Spring 让我们能够很容易透明地创建并绑定一个 Session 到当前线程。你可以使用以下两种办法之一:通过使用一个外部的 template 包装类在 Java 代码层次实现,或者通过 Hibernate SessionFactory 暴露当前 Session 对象(对于那些建立在 Hibernate3 原生的 API 上的 DAO )。这样,对于任何的事务环境(本地事务或者 JTA ), Spring 解决了许多在 Hibernate 使用中不断出现的这样那样的问题。
4)     综合的事务管理。 Spring 允许你封装你的O/R Mapping代码,这可以通过声明式的AOP方法拦截器或者在Java代码级别上使用一个外部的template包装类。无论使用哪一种方式,事务控制都会帮助你做相关处理,例如万一有异常发生时的事务操作(rollback)。正如我们下面要讨论的一样,你能够使用和替换各种事务管理器,却不会使你的Hibernate/JDO相关的代码受到影响。例如,不管采用本地事务还是JTA,完整的Service层的代码(如声明式事务管理)在这种场景下都是相同的。作为一个附加的功能,JDBC相关的代码能够在事务级别上与你所使用的O/R映射代码无缝整合。这一功能对于那些诸如批量处理、BLOB的操作等并不适合采用O/R Mapping操作的,但是需要与O/R Mapping操作一起参与相同的事务来说是相当有用的。
5)      避免绑定特定技术允许 mix-and-match 的实现策略。 虽然 Hibernate 非常强大、灵活、开源而且免费,但它还是使用了自己的特定的 API 。此外,有人也许会争辩: iBatis 更轻便而且在不需要复杂的 O/R 映射策略的应用中使用时能够表现得非常优秀。如果可以选择的话,使用标准或抽象的 API 来实现主要的应用需求通常是更好的,尤其是当你可能会因为功能、性能或其他方面的原因而需要切换到另一种实现的时候。举例来说, Spring Hibernate 事务和异常抽象,允许你通过 IoC 机制轻松封装 mapper DAO 对象来实现数据访问功能,这些特性都能够使你在 不牺牲 Hibernate 强大功能 的情况下在你的应用程序中隔离 Hibernate 的相关代码。处理 DAO 的高层次的 service 代码无需知道 DAO 的具体实现。这一机制可以很容易使用 mix-and-match 方案互不干扰地实现数据访问层(比如在一些地方用 Hibernate ,一些地方使用 JDBC ,其他地方使用 iBatis ), mix-and-match 的特性也有利于处理遗留代码并在各种技术( JDBC Hibernate iBatis )之间取长补短。
我们将首先从 Hibernate 开始,通过讲解 Hibernate Spring 环境中的使用来阐述 Spring 框架对于 O/R Mapping 工具的整合方式。本章节将涉及到许多细节问题,并向你展示各种不同的 DAO 实现方式和事务划分。这其中的绝大多数模式能够被 Spring 支持的其他 O/R Mapping 工具所使用。为了避免硬编码的资源查找与应用程序对象紧密耦合, Spring 允许你在 application context 中以 bean 的方式定义诸如 JDBC DataSource 或者 Hibernate SessionFactory 的数据访问资源。任何需要进行资源访问的应用程序对象只需要持有这些事先定义好的实例的引用,下面的代码演示如何创建一个 Hibernate SessionFactory
代码清单1
<!-- 定义 dataSource -->
< bean id = "dataSource" class = "net.sourceforge.jtds.jdbc.Driver" >
    < property name = "driverClassName"
           value = "net.sourceforge.jtds.jdbc.Driver" />
    < property name = "url"
value = "jdbc:jtds:Sqlserver://10.0.160.188:1433/WPE" />
    < property name = "username" value = "sa" />
    < property name = "password" value = "sa" />
</ bean >
   
< bean id = "mySessionFactory"
class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
    < property name = "dataSource" ref = "dataSource" />
    < property name = "mappingResources" >
      < list >
        < value > product.hbm.xml </ value >
      </ list >
    </ property >
    < property name = "hibernateProperties" >
      < value >
        hibernate.dialect=org.hibernate.dialect.MySQLDialect
      </ value >
</ property >
</ bean >
public class HibernateDAO extends HibernateDaoSupport {
    public void save(User uaer){
        this .getHibernateTemplate().save(user);
    }
}
在代码清单 1 中我们定义了一个数据源并且通过这个数据源我们创建了一个 Hibernate SessionFactory ,通过 Spring SessionFactory 注入进 HibernateDAO ,在 save 方法中调用 HibernateTemplate save 方法将 User 对象持久化入数据库。
 
我的其它Spring文章,也许会对您有帮助
 
Spring的任务调度和邮件发送
 
Spring应用的单元测试
 
Spring的数据库支持
 
Spring的MVC框架
 
Spring的IoC容器
 
Spring对AOP的支持
 
Spring2.5注释驱动与基于注释的MVC
 

你可能感兴趣的:(java,spring,jdbc,休闲,绝缘材料)