微信号:javajidi_com

介绍:专注Java与Web技术的研究;分享有价值的技术;经验;关注程序员的发展.

Spring DAO理念

2016-06-01 21:52 强哥

DAO(Data Access Object)是用于访问数据的对象,虽然我们在大多数情况下,将数据保存在数据库中,但这并不是唯一的选择,你也可以将数据存储到文件中或LDAP中。DAO不但屏蔽了数据存储的最终介质的不同,也屏蔽了具体的实现技术的不同。 


早期,JDBC是访问数据库的主流选择,近几年,数据持久技术获得了长足的发展,Hibernate、iBatis、JPA、JDO成为持久层中争放异彩的实现技术。只要为数据访问定义好DAO接口,并使用具体的技术实现DAO接口的功能,你就可以在不同的实现技术间平滑的切换。



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


    提供DAO层的抽象可以带来一些好处,首先,我们可以很容易地构造模拟对象,方便单元测试的开展,其次在使用切面时,我们有更多的选择:既可以使用JDK动态代理也可以使用CGLib动态代理。 


    Spring本质上希望以统一的方式整合底层的持久化技术:以统一的方式进行调用及事务管理,避免让具体的实现侵入到业务层的代码中。由于每个持久化实现技术都有各自的异常体系,所以Spring提供了统一的异常体系,使不同异常体系的阻抗得以弥消,方便定义出和具体实现技术无关的DAO接口,以及整合到相同的事务管理体系中。


统一的异常体系是整合不同的持久化实现技术的关键,Spring提供了一套和实现技术无关的、面向于DAO层次语义的异常体系,并通过转换器将不同的持久化技术异常转换成Spring的异常。   


 在很多正统API或框架中,检查型异常被过多的使用,以至在使用API时,代码里充斥着大量的try/catch样板式的代码。在很多情况下,除了在try/catch中记录异常信息以外,我们并没有做多少实质性的工作。引发异常的问题往往是不可恢复的,如数据连接失败,SQL语句存在语法错误,强制捕捉的检查型异常除了限制开发人员的自由度以外,并没有提供什么有意义的作用。因此,Spring的异常体系都是建立在运行期异常的基础上,开发者可以根据需要捕捉感兴趣的异常。 


    Spring在org.springframework.dao包中提供了一套完备优雅的DAO异常体系,这些异常都继承于DataAccessException,而DataAccessException本身又继承于NestedRuntimeException,NestedRuntimeException异常以嵌套的方式封装了源异常。因为虽然不同持久化技术的特定异常被转换到Spring的DAO异常体系中,原始的异常信息并不会丢失,只要你愿意,就可以方便地通过getCause()方法获取原始的异常信息。

 
    Spring的DAO异常体系并不和具体的实现技术相关,它从DAO概念的抽象层面定义了异常的目录树。在所有的持久化框架中,我们并没有发现拥有如此丰富语义异常体系的框架,Spring这种设计无疑是独具匠心的,它使得开发人员关注某一特定语义的异常变得容易。在JDBC中的SQLException中,你必须通过异常的getErrorCode()或getSQLState()获取错误代码,直接根据这些代码判断是错误的类型,这种过于底层的API不但带来了代码编写上的难度,而且也使代码的移植变得困难,因为getErrorCode()是数据库相关的。 


    Spring以分类手法建立了异常分类目录,对于大部分应用来说,这个异常分类目录对异常类型的划分具有适当的颗粒度。一方面,使开发者从底层细如针麻的技术细节中脱身出来,另一方面,可以从这个语义丰富的异常体系中选择感兴趣的异常加以处理。图 2列出了那些位于Spring DAO异常体系第一层次的异常类,每个异常类下还可能拥有众多的子异常类:



    统一数据访问模板 
    到一个餐馆用餐,大抵都会经历这个的一个流程,进入餐馆->迎宾小姐问候并引到适合的位置->抄起菜单点菜>用餐->买单->离开餐馆。之所以我们喜欢时不时下下馆子,就是因为我们只要点菜->用餐->买单就可以了,幕后的烹饪制作、刷锅洗盘等工作我们完全不用关心,一切已经由餐馆服务人员按照服务流程按部就班,有条不紊地执行了。衡量一个餐馆服务质量好坏的一个重要标准是我们无须关心他们所负责流程:不用催问菜为什么还没有上好(不但快而且服务态度佳),不用关心盘子为什么不干净(不但干净而且已经进行了消毒)。 


    从某种角度看,与其说餐馆为我们提供了服务,还不如说我们参与到餐馆的流程中:不管什么顾客点的菜都由相同的橱师烹制,不管什么顾客都按单付钱。在幕后,餐馆拥有一个服务的模板,模板中定义的流程可以用于应付所有的顾客,只要为顾客提供几个专有需求(点的菜也可不一样,座位可以自由选择),其它一切都按模板化的方式处理。 


    在直接使用具体的持久化技术时,我们大多需要处理整个流程,并没有享受餐馆用餐式的便捷。Spring为支持的持久化技术分别提供了模板访问的方式,降低了使用各种持久化技术的难度,可以大幅提高开发效率。 

 
Java技术 更多文章 准备进入码农行业?你准备好了吗 Java是怎样运行的,你敢说真的知道? Java:怎样理解byte的最大值是2^7-1 交换思想在程序设计中的应用 Java:线程初识
猜您喜欢 C++多线程编程中需要使用volatile吗? 没落的公司 该何去何从 使用Google官方support-annotation利器 这些面试题,做对了你也能进BAT! 用例多,工作量大,bug却少,测试中你会缺陷预估吗?