您的位置:首页 > 编程语言 > Java开发

Spring对DAO的支持(精通Spring+4.x++企业应用开发实战 第十章)

2017-09-29 10:39 711 查看

Spring的DAO概念

DAO(Data Access Object)是用于访问数据的对象

下图是一个典型的DAO应用实例,在UserDao中定义访问User数据对象的接口方法,业务层通过UserDao操作数据,并使用具体的持久化技术实现UserDao接口方法,这样业务层和具体的持久化技术就实现了解耦



提供DAO层的抽象,可以很容易地构造模拟对象,方便单元测试的开展;在使用切面时会有更多的选择,既可以使用JDK动态代理,又可以使用CGLib动态代理

统一的异常体系

Spring的DAO异常体系

Spring在spring.framework.dao包中提供了一套DAO异常体系。这些异常都继承于DataAccessException,而DataAccessException本身又继承于NestedRuntimeException,NestedRuntimeException异常以嵌套的方式封装了源异常。可以通过getCause()方法获取原始的异常信息







为了进一步细化错误的问题域,Spring对一级异常类进行了子类的细分,如InvalidDataAccessResourceUsageException就拥有十多个子类。不同的持久化技术具有对应额自异常子类



JDBC的异常转换器

传统的JDBC API在发生几乎所有的数据操作问题时会抛出相同的SQLException,将异常的细节性信息封装在异常属性中。

SQLException拥有两个代表异常具体原因的属性:错误码和SQL状态码。

错误码是数据库相关的,可通过getErrorCode()返回,类型是int

SQL状态码是一个标准的错误代码,可通过getSQLState()返回,类型是String,由5个字符组成。

Spring根据错误码和SQL状态码信息将SQLException译成Spring DAO的异常体系对应的异常。

在org.springframework.jdbc.support包中定义了SQLExceptionTranslator接口,其两个实现类SQLErrorCodeSQLExceptionTranslator和SQLStateSQLExceptionTranslator分别负责处理SQLException中错误码和SQL状态码的翻译工作

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



统一数据访问模板

Spring为支持的持久化技术分别提供了模板访问的方式,降低了使用各种持久化技术的难度,可以大幅度地提高开发效率。

使用模板和回调机制

JDBC数据访问操作按以下流程进行

①准备资源

②启动事务

③在事务中执行具体的数据访问操作

④提交/回滚事务

⑤关闭资源,处理异常





Spring将这个相同的数据访问流程固化到模板类中,并将数据访问中固定和变化的部分分开,同时保证模板类是线程安全的,以便多个数据访问线程共享同一个模板实例。

固定的部分在模板类中已经准备好,而变化的部分通过回调接口开放出来,用于定义具体数据访问和结果返回的操作。

下图描述了模板类拆分固定和变化部分的逻辑



只要编写好回调接口,并调用模板类进行数据访问,就可以得到预想的结果:数据访问成功执行,前置或后置的样板化工作也按顺序正确执行,在提高开发效率的同时保证了资源使用的正确性,彻底消除了因忘记进行资源释放而引起的资源泄漏问题

Spring为不同持久化技术所提供的模板类



如果直接使用模板类,一般需要在DAO中定义一个模板对象并提供数据资源。Spring为每种持久化技术都提供了支持类,支持类中已完成了这样的功能。只需扩展这些支持类,就可以直接编写实际的数据访问逻辑,更加方便



这些支持类都继承于dao.support.DaoSupport,它实现了InitializingBean接口,在afterPropertiesSet()接口方法中检查模板对象和数据源是否被正确设置,否则将抛出异常。

所有支持类都是abstract,目的是被继承使用而非直接使用

数据源

在Spring中,数据连接是通过数据源获得的。

配置一个数据源

Spring在第三方依赖包中包含了两个数据源的实现类包:Apache的DBCP和C3P0

1.DBCP数据源(DataBase Connection Pool,数据库连接池)

DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池,所以在类路径下还必须包括commons-pool的类包。

使用DBCP配置MySQL数据源的片段:



BasicDataSource提供了close()方法关闭数据源,必须设定destory-method=”close”属性,以便Spring容器关闭时,数据源能正常关闭。

还有一些常用的属性











如果采用默认配置,testOnBorrow属性的默认值为true,数据源在将连接交给DAO前,会事先检查这个连接是否好的,如果连接有问题(在数据库端被关闭),则会取一个其他的连接给DAO。

如果每次将连接交给DAO都检查连接的有效性,在高并发的应用中将会带来性能问题,因为它需要更多的数据库访问请求。

一种推荐的高效方式是:将testOnBorrow设置为false,而testWhileIdle设置为true,再设置好timeBetweenEvictionRunsMillis值。

这样,DBCP将通过一个后台编程定时地对空闲连接进行检查,当发现无用的空闲连接(那些被数据库关闭的连接)时,就会将它们清除掉。

MySQL本身可以通过调整interactive-timeout(秒为单位)配置参数,更改空闲连接的过期时间,所以在设置timeBetweenEvictionRunsMillis值时,必须首先获知MySQL空闲连接的最大空闲时间。

2.C3P0数据源

C3P0
bc46
是一个开源的JDBC数据源实现项目,实现了JDBC3和JDBC2扩展规范说明的Connection和Statement池。

使用C3P0配置一个Oracle数据源



ComboPooledDataSource一样提供了一个用于关闭数据源的close(0方法,这样可以保证Spring容器关闭数据源能够被成功释放。

配置属性









3.使用属性文件

一般将数据源的配置信息独立到一个属性文件中,通过<context:property-placeholder>引入属性文件,以${xxx}的方式引用属性



在属性文件中定义属性值



获取JNDI数据源(Java Naming and Directory Interface,Java命名和目录接口)

应用服务器的数据源使用JNDI开放调用者使用,Spring提供了引用JDNI数据源的JndiObjectFactoryBean类



通过jndiName指定引用的JNDI数据源名称。

Spring为获取Java EE数据源提供了一个jee命名空间,通过jee命名空间,可以有效地简化Java EE资源的引用



Spring的数据源实现类

Spring提供了一个简单的数据源实现类DriverMannagerDataSource,位于org.springframework.jdbc.datasource包中。它实现了javax.sql.DataSource接口,但并没有提供池化连接的机制;每次调用getConnection()方法获取新连接时,只是简单地创建一个新的连接



也可以通过配置的方式直接使用该类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring