Spring对DAO的支持

Spring对DAO的支持

近几年,数据库持久化技术得到了长足的发展,HibernateMyBatisJPA等成为持久层争放异彩的实现技术。一个典型的DAO应用实例如下图:

userdaodemo.png

UserDao中定义访问User数据对象的接口,并使用具体的持久化技术实现期中的接口方法,业务层通过UserDao操作数据,这样就使得业务层与具体的持久化实现技术实现了解耦

使用Dao抽象层带来的好处:

1.使得业务层与具体的持久化实现技术实现了解耦,使得代码高内聚,低耦合。
2.面向接口编程使得代码可以很容易的构建模拟对象,方便展开单元测试。

Spring希望以统一的方式整合不同的持久化实现技术,即使得用户以统一的方式进行调用和事务控制,避免具体的持久化实现侵入到业务层代码。为了实现这个目标,Spring统一了各个持久化实现技术的异常体系(每个持久化技术都有自己的异常体系),并且提供了统一的数据访问模板,方便用户使用

统一的异常体系

背景

很多正统API或者框架中,检查型异常被过多的使用,以至于我们使用其API时,代码中充斥着try/catch样板式代码。在很多时候,这些try/catch除了记录异常信息以外,很难做一些实际工作(引发异常的问题往往是不可恢复的,如:数据库连接失败、SQL语句错误等),强制开发人员捕获此类检查型异常除了限制开发人员以外,并没有做有价值的东西。

Spring的Dao异常体系

为解决此类问题,Spring将各个框架的异常(特别是受检异常)转化为其统一的异常体系。这些异常都继承于DataAccessException,而DataAccessException本身又继承于NestedRuntimeException,这样将受检异常转化为非受检异常。而NestedRuntimeException以嵌套方式封装了异常的源信息,开发人员随时可以使用getCause()获取异常原因。

其异常体系的顶层异常如下:

exceptiontree.png

异常 说明
CleanupFailureDataAccessException Dao操作执行成功,但在释放数据资源时发生异常,如:关闭Connection异常
ConcurrencyFailureException 并发数据操作时发生异常:锁无法获取、死锁异常等
DataAccessResourceFailureException 获取数据资源时发生异常:获取Connection失败、获取Hibernate Session失败等。
DataRetrievalFailureException 获取数据失败,找不到主键、使用错误索引等。
DataSourceLookupFailureExcption 无法从JNDI中查找数据源
DataIntegrityViolationException 数据违反了一致性约束:插入重复主键、引用不存在的外键等
InvalidDataAccessApiUsageException 不正确的调用持久化技术API导致的异常:如Spring JDBC中查询对象,必须在调用前进行编译,如果忘记编译则会导致异常。
InvalidDataAccessResourceUsageException 访问数据源时调用了不正确的方法导致的异常:如SQL语句错误
PermissionDeniedDataAccessException 权限不足引发的异常
UncategorizedDataAccessException 其他为分类的异常

该异常体系具有高度可扩展性。为进一步细化错误问题域,Spring对顶层异常进行了细分。例如:光是InvalidDataAccessResourceUsageException就有十多个子类。如BadSqlGrammarException对应JDBC异常的语法错误,HibernateQueryException对应Hibernate查询异常。

InvalidDataAccessResourceUsageException.png

异常转换的实现

JDBC的异常转换

传统的JDBC API在发生数据操作异常时机会都会抛出SQLException,并将异常细节信息封装在异常属性中。用户通过getErrorCode()获取错误码,该错误码与数据库紧密相关或通过getStateCode()获取SQL状态码。Spring根据错误码和SQL状态码将SQLException转化为其DAO异常体系中的相应异常。

exceptiontranslator.png

其他持久化技术的异常转换

由于每个持久化技术都有其语义明确的异常体系,所以这些异常转化为Spring的异常体系相对轻松些。Spring同样为每个持久化技术都提供的定制的异常转换器。

| ORM

持久化技术 异常转换器
Hibernate org.springframework.orm.hibernate5.SessionFactoryUtils
JPA org.springframework.orm.jpa.EntityManagerFactoryUtils
注:MyBatis使用与JDBC相同的异常体系,因此与JDB异常转换相同

统一的数据访问模板

背景

参见 Spring理念  一节中的相关介绍。

不同持久化技术的使用模板

Spring为各种持久化技术都提供了简化操作模板和回调,在回调中编写具体的数据操作逻辑,而获取连接、处理异常、释放连接交由模板代码自动完成。这使得用户专注于业务代码,从单调繁杂的无关处理中解脱。

Spring提供的模板如下:

| ORM

持久化技术 模板类
Hibernate org.springframework.orm.hibernate5.HibernateTemplate
JPA org.springframework.orm.jpa.JpaTemplate(已废弃,使用EntityManager)
JDBC org.springframework.jdbc.core.JdbcTemplate

如果直接使用模板类,则需要在Dao中定义模板对象,并提供数据源。Spring为减少这一工作同样提供了支持类,用户只需要扩展这些支持类就可以直接使用模板类。

posted @ 2023-01-31 14:46  小张同学哈  阅读(90)  评论(0)    收藏  举报