Spring整理记录之JDBC

Spring提供的DAO(数据访问对象)支持目的是便于以一致的方式使用不同的数据访问技术, 如JDBC,Hibernate或者JDO等。
它不仅可以让你方便地在这些持久化技术间切换, 而且让你在编码的时候不用考虑处理各种技术中特定的异常。

Spring提供了一种方便的方法,把特定于某种技术的异常,如SQLException, 转化为自己的异常,这种异常属于以DataAccessException 为根的异常层次。
这些异常封装了原始异常对象,这样就不会有丢失任何错误信息的风险。

为了便于以一种一致的方式使用各种数据访问技术,如JDBC、JDO和Hibernate, Spring提供了一套抽象DAO类供你扩展。
JdbcDaoSupport - JDBC数据访问对象的基类。 需要一个DataSource,同时为子类提供 JdbcTemplate。
HibernateDaoSupport - Hibernate数据访问对象的基类。 需要一个SessionFactory,同时为子类提供 HibernateTemplate。也可以选择直接通过 提供一个HibernateTemplate来初始化, 这样就可以重用后者的设置,例如SessionFactory, flush模式,异常翻译器(exception translator)等等。
JdoDaoSupport - JDO数据访问对象的基类。 需要设置一个PersistenceManagerFactory, 同时为子类提供JdoTemplate。
JpaDaoSupport - JPA数据访问对象的基类。 需要一个EntityManagerFactory,同时 为子类提供JpaTemplate。



Spring JDBC抽象框架所带来的价值将在以下几个方面得以体现:
定义数据库连接参数
打开数据库连接
声明SQL语句
预编译并执行SQL语句
遍历查询结果(如果需要的话)
处理每一次遍历操作
处理抛出的任何异常
处理事务
关闭数据库连接
使用了Spring JDBC抽象框架之后,应用开发人员只需要完成部分的编码工作:声明SQL语句,处理每一次遍历操作。

使用Spring进行基本的JDBC访问数据库有多种选择。Spring至少提供了三种不同的工作模式:
JdbcTemplate - 这是经典的也是最常用的Spring对于JDBC访问的方案。
NamedParameterJdbcTemplate - 对JdbcTemplate做了封装,提供了更加便捷的基于命名参数的使用方式而不是传统的JDBC所使用的“?”作为参数的占位符。
SimpleJdbcTemplate - 这个类结合了JdbcTemplate和NamedParameterJdbcTemplate的最常用的功能,同时它也利用了一些Java 5的特性所带来的优势。
SimpleJdbcInsert 和 SimpleJdbcCall - 这两个类可以充分利用数据库元数据的特性来简化配置。
RDBMS 对象包括MappingSqlQuery, SqlUpdate and StoredProcedure - 这种方式允许你在初始化你的数据访问层时创建可重用并且线程安全的对象。

Spring Framework的JDBC抽象框架由四个包构成:core、 dataSource、object以及support。
在JDBC调用过程中所抛出的异常都会被转化为在org.springframework.dao包中定义的异常。
也就是说,凡是使用Spring的JDBC封装层的代码无需实现任何JDBC或者RDBMS相关的异常处理。
所有的这些被转化的异常都是unchecked异常,因而也给了你一种额外的选择,你可以抓住这些异常,从而转化成其他类型的异常被允许调用者传播。


JdbcTemplate是core包的核心类。
它替我们完成了资源的创建以及释放工作,从而简化了我们对JDBC的使用。
它还可以帮助我们避免一些常见的错误,比如忘记关闭数据库连接。
JdbcTemplate将完成JDBC核心处理流程,比如SQL语句的创建、执行,而把SQL语句的生成以及查询结果的提取工作留给我们的应用代码。
它可以完成SQL查询、更新以及调用存储过程,可以对ResultSet进行遍历并加以提取。
它还可以捕获JDBC异常并将其转换成org.springframework.dao包中定义的,通用的,信息更丰富的异常。

使用JdbcTemplate进行编码只需要根据明确定义的一组契约来实现回调接口:
PreparedStatementCreator回调接口通过给定的Connection创建一个PreparedStatement,包含SQL和任何相关的参数。
CallableStatementCreateor实现同样的处理,只不过它创建的是CallableStatement。
RowCallbackHandler接口则从数据集的每一行中提取值。

可以在DAO实现类中通过传递一个DataSource引用来完成JdbcTemplate的实例化,
也可以在Spring的IoC容器中配置一个JdbcTemplate的bean并赋予DAO实现类作为一个实例。
需要注意的是DataSource在Spring的IoC容器中总是配制成一个bean。
第一种情况下,DataSource bean将传递给service,第二种情况下DataSource bean传递给JdbcTemplate bean。


execute(..)方法可以被用作执行任何类型的SQL,甚至是DDL语句。 这个方法的实现需要传入一个回调接口、需要绑定的参数数组等作为参数。

JdbcTemplate类的实例是线程安全的实例。这一点非常重要。
正因为如此,你可以配置一个简单的JdbcTemplate实例,并将这个“共享的”、“安全的”实例注入到不同的DAO类中去。
另外, JdbcTemplate 是有状态的,因为他所维护的DataSource 实例是有状态的,但是这种状态是无法变化的。

使用JdbcTemplate的一个常见的最佳实践(同时也是SimpleJdbcTemplate和NamedParameterJdbcTemplate 类的最佳实践)就是在Spring配置文件中配置一个DataSource实例,然后将这个共享的DataSource实例助于到你的DAO中去。

一般情况下,无需多次创建JdbcTemplate实例,一旦JdbcTemplate被创建,他是一个线程安全的对象。
一个你需要创建多次JdbcTemplate实例的理由可能在于,你的应用需要访问多个不同的数据库,从而需要不同的DataSources来创建不同的JdbcTemplates实例。


NamedParameterJdbcTemplate类为JDBC操作增加了命名参数的特性支持,而不是传统的使用('?')作为参数的占位符。
NamedParameterJdbcTemplate类对JdbcTemplate类进行了封装, 在底层,JdbcTemplate完成了多数的工作。

NamedParameterJdbcTemplate类所具备的另外一个比较好的特性就是可以接收SqlParameterSource作为传入参数 (这个类位于相同的包定义中)。

SimpleJdbcTemplate所提供的一些特性必须工作在Java 5及以上版本。
SimpleJdbcTemplate类完全利用了Java 5语法所带来的蜜糖效应。
凡是使用过Java 5的程序员们如果要从Java 5迁移回之前的JDK版本,无疑会发现这些特性所带来的蜜糖效应。

“before and after”示例可以成为SimpleJdbcTemplate类所带来的蜜糖效应的最佳诠释。

SimpleJdbcTemplate只是提供了JdbcTemplate所提供的功能的子类。
如果你需要使用JdbcTemplate的方法,而这些方法又没有在SimpleJdbcTemplate中定义,你需要调用getJdbcOperations()方法 获取相应的方法调用。

为了从数据库中取得数据,我们首先需要获取一个数据库连接。
Spring通过DataSource对象来完成这个工作。
DataSource是JDBC规范的一部分,它被视为一个通用的数据库连接工厂。
通过使用DataSource, Container或Framework可以将连接池以及事务管理的细节从应用代码中分离出来。

SQLExceptionTranslator是一个接口,如果你需要在 SQLException和org.springframework.dao.DataAccessException之间作转换,那么必须实现该接口。
SQLErrorCodeSQLExceptionTranslator是SQLExceptionTranslator的默认实现。


JDBC驱动针对批量调用相同的prepared statement对象提供了性能提升。通过将这些更新操作封装到一个批量操作中,可以大量减少与数据库的操作频繁度。

JdbcTemplate的批量操作特性需要实现特定的接口BatchPreparedStatementSetter来进行的, 通过实现这个接口,并将其传入batchUpdate方法进行调用。
这个接口有两个方法需要实现:
一个叫做getBatchSize来提供当前需要批量操作的数量。
另一个方法是setValues 允许你为prepared statement设置参数。这个方法将在整个过程中被调用的次数,则取决于你在getBatchSize中所指定的大小。

SimpleJdbcTemplate类提供了另外一种批量操作的方式。
无需实现一个特定的接口,你只需要提供所有在调用过程中要用到的参数,框架会遍历这些参数值,并使用内置的prepared statement类进行批量操作。API将根据你是否使用命名参数而有所不同。
对于使用命名参数的情况,你需要提供一个SqlParameterSource的数组, 其中的每个元素将将作为批量操作的参数。
你可以使用SqlParameterSource.createBatch方法,通过传入一个JavaBean的数组或者一个包含了参数键值对的Map数组来创建这个数组。

所有的批量更新的方法都会返回一组int的数组,表示在整个操作过程中有多少记录被批量更新。

SimpleJdbcInsert类和SimpleJdbcCall类主要利用了JDBC驱动所提供的数据库元数据的一些特性来简化数据库操作配置。
这意味着你可以尽可能的简化你的数据库操作配置。当然,你可以可以将元数据处理的特性关闭,从而在你的代码中详细指定这些特性。


SimpleJdbcInsert类必须在数据访问层的初始化方法中被初始化。

 


SimpleJdbcCall 来进行存储过程的调用上。 设计这个类的目的在于使得调用存储过程尽可能简单。它同样利用的数据库元数据的特性来查找传入的参数和返回值。 这意味着你无需明确声明那些参数。

 


org.springframework.jdbc.object包下的类允许用户以更加 面向对象的方式去访问数据库。
比如说,用户可以执行查询并返回一个list, 该list作为一个结果集将把从数据库中取出的列数据映射到业务对象的属性上。
用户也可以执行存储过程,以及运行更新、删除以及插入SQL语句。

SqlQuery是一个可重用、线程安全的类,它封装了一个SQL查询。 其子类必须实现newResultReader()方法,该方法用来在遍历 ResultSet的时候能使用一个类来保存结果。

MappingSqlQuery是一个可重用的查询抽象类,其具体类必须实现 mapRow(ResultSet, int)抽象方法来将结果集中的每一行转换成Java对象。

SqlUpdate类封装了一个可重复使用的SQL更新操作。 跟所有RdbmsOperation类一样,SqlUpdate可以在SQL中定义参数。

StoredProcedure类是一个抽象基类,它是对RDBMS存储过程的一种抽象。 该类提供了多种execute(..)方法,不过这些方法的访问类型都是protected的。

SqlFunction RDBMS操作类封装了一个SQL“函数”包装器(wrapper), 该包装器适用于查询并返回一个单行结果集。默认返回的是一个int值, 不过我们可以采用类似JdbcTemplate中的queryForXxx 做法自己实现来返回其它类型。SqlFunction优势在于我们不必创建 JdbcTemplate,这些它都在内部替我们做了。

在Spring的JDBC框架的所有工作模式中贯彻了一些与参数和数据处理相关的基本原则。

可以在数据库中存储图像、二进制对象或者大文本等对象。这些较大的二进制对象被称之为BLOB类型,而对应的大文本对象被称之为CLOB对象。

当调用存储过程时,有时需要使用数据库特定的复杂类型。为了适应这些类型,Spring提供了SqlReturnType类来处理存储过程的返回值,而使用SqlTypeValue来处理传入的参数。

你可能感兴趣的:(DAO,spring,sql,bean,jdbc)