spring DAO体系结构

springDAO体系结构

在spring的众多应用中,对数据库的操作是一个很重要的部分,spring对DAO结构的抽象是一个非常值得研究的问题。这里并不打算讨论spring在数据库操作中的底层技术,例如数据库异常转换系统、事务抽象等,这里我只想讨论一下在数据库操作中与程序员接口的部分,即DAO接口的抽象。在spring中的对DAO接口的抽象主要分为两个部分,第一个部分是spring自己对jdbc的直接抽象;第二个部分是spring对第三方ORM框架的集成。Spring在对jdbc进行抽象的时候运用了一些很好的思想,例如回调、映射、模板方法等,当然在对其它ORM框架进行集成的时候也运用了这些思想,实际上可以把spring对jdbc接口的直接抽象看成是一个小型的DAO框架,可以与其它ORM框架放在同样重要的位置进行研究,不论是spring自已对jdbc进行抽象,还是对第三方的ORM框架进行集成,基本都遵循一种雷同的模式。

在spring的DAO体系中主要有以下几种类型的组件:最上层为DaoSupport类型,它可以看成是Template类型类的工厂类,它负责Template类型类的实例创建,少量周边资源的管理,例如连接、DataSource、Session等,并规范实例的创建流程。这种类型的类在实际开发中通常都是程序员需要直接继承的类;其次为Template类型的类,这种类型的类是spring抽取数据库实际操作的核心类型,它是对Operations类型的接口的实现,具体的关系可以参考下面图(1)在前两组中并没有画出DoaSupport类,第三组Hibernate的集成图最完整。

从下面三组高度抽象的结构图可以可看出:Operations、Accessor与Template三者是紧密相连的。Accessor类型的类主要用来规范Template的创建,它的原意应该是“访问器”之类意思,在这里它主要为Template提供必要的基础设施,除了一些便利的工具方法,最重要的功能应该是创建并管理访问数据库的对象,根据框架的不同这些对象也是不同的,可能是底层的DataSource,也可能是高层的SessionFactory,Template并不负责这些基础设施的管理,它主要负责Operations接口的实现,Operations接口是程序员最频繁使用的接口,可以说Operations接口就是对数据库增、删、查、改操作的抽象,但这里有一个非常遗憾的事情,Operations接口并不是一个规范的接口,它是与环境相关,与框架相关。

图(1)

通过对各种Operations接口的分析,可以找出各个框架的关键点与框架的自身特点,这里主要以JdbcOperations、SqlMapClientOperations(iBatis2)、HibernateOperations为例进行分析。在进行分析之前有必要对jdbc的API有所了解,因为所有框架都是建立在jdbc的规范之上,因此各种各样的框架虽然有着较大的差异,但它们必定都会存在jdbc的影子。Jdbc规范在执行数据库操作的时候,主要分为以下几个重要的步骤。获取连接;创建Statement;设置参数;执行语句;处理结果。具体的流程可以参考勤JDBC类图

图(2)

在jdbc的整个操作中有几点是需要注意的,SQL语句通常是必不可少的,一般情况参数设置也是需要的,如果是查询,结果的处理也是少不了的。对于持久层框的研究我认为也需要从这些方面去加深认识,如何获取SQL,如何设置参数,如何抽取结果。

对于JdbcOperations可以看到SQL语句是需要程序员直接在程序中指定的,参数的设置与结果的提取,框架都抽取相应的回调接口例如:PreparedStatementCreator、ResultSetExtractor等,但最终的设置与抽取逻辑是要靠程序员手工来完成的。这是jdbcOperations操作接口最大的弱点,spring在抽取jdbcDaoSupport的过程中并没有使用配置文件,这是导致sql语句的提供、参数设置、结果抽取都需要程序员手工操作完成的一个很重要原因,因为它根本就不是作为持久层来设计的,它只是为了使程序员在使用jdbc的过程相对容易一些,只是jdbc的基本包装。虽然JdbcOperations的抽象缺陷非常的明显,但它的设计方式却是非常值得研究的,尤其是如果你自己打算设计一个持久层的框架时更是如此,它在其中使用大量的模板方法模式来简化重复机械的操作。

SqlMapClientOperations接口是对iBatis框架的操作抽象,它的接口相对要简单一些,接口参数主要以语句标识和参数对象为主,如果你阅读过iBatis框架的源程序,你会发现框架的底层代码仍然是jdbc,它最终需要解决的问题就是获取SQL,设置参数,抽取结果,当然这里说了一些废话,应该说不只iBatis框架最终关注这些问题,实际所有持久层框架它们最终的目标都是以一种便利的方式来解决这几个问题,最终这种“便利的方式”会形成一套框架规则。因此在学习各种持久层框架时一定抓住框架所需要解决的这几个核心问题。iBatis框架是如何完成这几个问题的呢?关键在语句标识,在程序中它虽然只是一个语句标识,但它实际表示一个语句配置,可以说它包含了解决上述三个问题的配置信息,至于它是如何通过配置来解决这几个问题需要单独分析,这里就不详加分析。对于iBatis来说我认为有两不足,第一基本的操作配置不能自动生成;第二大部分组件只能配置中完成,不能由程序员在程序中手工配置,这显得程序过于机械。

HibernateOperations接口是对Hibernate框架的操作抽象,根据Hibernate框架的特点接口主要围绕着“类”为中心,或者说是以对象为中心,因此在接口中出现了很多类型参数与类名称参数,此特点的操作主要集中在增(save)、删(delete)、改(update)、简单查询(get、load)等操作上,至于复杂的查询可能走了另一种转换体系。为什么会在大量的操作中出现“类”与“类名称”参数呢?这是由框架的特点所决定,Hibernate框架主要是以对象的思想来设计框架的,即设计者想按一个一个对象来操作数据库,前面我们已经分析过所有持久层框架最终还是要以jdbc来操作数据库,所以Hibernate就必须有一套由“类”信息向数据库配置信息过渡,进而解决数据操作的几个关键问题(获取SQL、设置参数、抽取结果),因此在接口中大量指定“类”型参数,主要是需要通过“类”信息来获取配置信息。

通过对前面几个典型框架的分析,可以发现API的形态是完全不一样,它们是由框架自身的特点所决定的,虽然它们的目标在某种程度上是一致的,比如除去jdbcTemplate其它API都需要有一种方式来获取相关配置信息的“线索”;框架很可能会抽取自身的条件组件,虽然iBatis的动态条件是在配置中直接体现的,但其它一些持久层框架一般都有在程序中表达动态条件的组件,以支持有效的查询;还可能会有分页组件。虽然它们有很多共同点,但是要将这些共同点抽取出来似乎不太可能,因为需要兼顾的问题实在太多,我们是不是应该在这众多的持久层框架之上抽取一个共同的层,我不是很明确,但是如果有这样一个共同层那当然是好的,这样可以很轻松的在各种持久层框架之间进行切换,但在对众多持久层框研究你会发现这样的抽象是艰难的。

图(3)

图(4)

图(5)

图(6)

图(7)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值