技术开发 频道

基于Spring的DAO层设计



    概述
    Spring为各种支持的ORM提供了统一基于模板模式的Template基类,此外还为使用模板类提供了方便的Support支持类,它内容包含了一个Template,Spring推荐开发者直接继承这个Support类定义自己的DAO。但是,在实际应用中,直接继承Spring的Support定义实体类DAO存在一些不足之处,我们将探讨通过引入一个基类简化子类的编码的思路。

    此外,Spring提供的各种ORM Template类的查询方法使用Object[]传递查询条件参数,很多开发者发现使用Object[]传递查询条件并非是一个最优的办法,因此出现了很多演化的查询方法的设计方式,本文对此进行了汇总,大家可以通过比较选择自己认为最适合的方式。

    DAO基类的设计
    虽然Spring通过模板类和支持类为各种ORM框架提供了出色的支持,但也存在一些不足。首先,这些模板类大多都是不支持泛型的,对于保存、更改、删除等操作,泛型的意义并不是很大,但对于加载实体,查询实体集合的操作,泛型可以带来很大的方便。其次,由于支持类通过类似于getHibernateTemplate()、getSqlMapClientTemplate()的方式向子类开放模板类,子类在执行数据操作时,必须采取诸如:getSqlMapClientTemplate().insert("addForum", forum)的形式,子类代码显得比较拖沓。
    在实际应用中,开发者一般会在Spring支持类的基础上编写自己的DAO其类,进行自己的封装,以获得泛型的支持并提供自己的代理方法使子类避免显式调用模板类的代码。DAO基类并不需要对模板类的所有方法进行代理,仅对常用的方法(如CRUD操作方法)进行代理,而对不常用的方法则可要求子类显式调用模板实例完成。这样,一方面简化常用方法的调用,另一方面又使基类不过于复杂。

    由于一般的实体类对应的DAO都必须拥有CRUD操作,与其在每个实体DAO接口中复杂定义这些方法,不如提供一个通用的DAO接口。具体的实体DAO接口可以扩展这个通用DAO接口并定义实体类相关的其它操作方法就可以了。以Hibernate为例,图 2中给出了典型的DAO类的结构:

    Spring为各种支持的ORM提供了统一基于模板模式的Template基类,此外还为使用模板类提供了方便的Support支持类,它内容包含了一个Template,Spring推荐开发者直接继承这个Support类定义自己的DAO。但是,在实际应用中,直接继承Spring的Support定义实体类DAO存在一些不足之处,我们将探讨通过引入一个基类简化子类的编码的思路。     此外,Spring提供的各种ORM Template类的查询方法使用Object[]传递查询条件参数,很多开发者发现使用Object[]传递查询条件并非是一个最优的办法,因此出现了很多演化的查询方法的设计方式,本文对此进行了汇总,大家可以通过比较选择自己认为最适合的方式。     虽然Spring通过模板类和支持类为各种ORM框架提供了出色的支持,但也存在一些不足。首先,这些模板类大多都是不支持泛型的,对于保存、更改、删除等操作,泛型的意义并不是很大,但对于加载实体,查询实体集合的操作,泛型可以带来很大的方便。其次,由于支持类通过类似于getHibernateTemplate()、getSqlMapClientTemplate()的方式向子类开放模板类,子类在执行数据操作时,必须采取诸如:getSqlMapClientTemplate().insert("addForum", forum)的形式,子类代码显得比较拖沓。     在实际应用中,开发者一般会在Spring支持类的基础上编写自己的DAO其类,进行自己的封装,以获得泛型的支持并提供自己的代理方法使子类避免显式调用模板类的代码。DAO基类并不需要对模板类的所有方法进行代理,仅对常用的方法(如CRUD操作方法)进行代理,而对不常用的方法则可要求子类显式调用模板实例完成。这样,一方面简化常用方法的调用,另一方面又使基类不过于复杂。     由于一般的实体类对应的DAO都必须拥有CRUD操作,与其在每个实体DAO接口中复杂定义这些方法,不如提供一个通用的DAO接口。具体的实体DAO接口可以扩展这个通用DAO接口并定义实体类相关的其它操作方法就可以了。以Hibernate为例,图 2中给出了典型的DAO类的结构:


图 2 DAO层类设计


BaseDao<T>通用基础接口对所有实体DAO接口的通用方法进行了抽象并提供泛型的支持,其代码如代码清单 12所示:
代码清单 12 BaseDao<T>:通用接口
package com.baobaotao.dao;
import java.io.Serializable;
import java.util.List;
public interface BaseDao<T> {
T get(Serializable id); ①通过泛型的支持,加载实体的方法仅需要一个主键就可以了
List<T> getAll(); ②直接返回强类型的集合类

③泛型并没有给保存、删除和更改的操作带来方便,因此这些方法可以不使用泛型
void save(Object o);
void remove(Object o);
void update(Object o);

}

0
相关文章