`

关于数据访问模式(三)—— Data Accessor模式

阅读更多

        拐弯抹角了两篇Post,说了一下重要性和很常见的一个词汇:Metadata,终于都到言归正传的时候了。今天我们先来看看数据访问模式当中使用得很频繁的一种模式——Data Accessor(也称为DAO,数据访问器)。
        不管你是用着ADO.NET还是JDBC,你都可以直接使用SQL(在ADO.NET中使用SqlCommand,JDBC则是使用Statement)去访问数据库。而且,在使用SQL之前,你还得建立与数据库的连接(Connection)。于是,像这些涉及数据访问的代码就会散布在应用程序当中,使得程序维护或是性能改善都难以实施。举个很简单的例子,如果在一个项目中,每个程序员都要自己去建立与数据库的连接,那么当你希望实现一个连接池(Connection Pool)以提高性能的时候,散布在应用程序各处的建立连接的代码就会令你疲于奔命。因为在这种紧密耦合的情况下,连接池的使用改变了建立连接的方式,从而导致大量的代码改动。为了能够让应用程序更具灵活性,我们通常都会采用一些策略来降低应用程序与数据库访问细节之间的耦合度。Data Accessor就是这些解耦合的策略相当重要的一条。
        Data Accessor的实质就是封装了对数据库访问的细节,仅对应用程序公开逻辑操作。Data Accessor封装细节的程度也就决定了其实现的复杂程度。最简单的一种Data Accessor实现就是由一个Support类提供通用的获得连接的方法,然后进行数据操作的类都必须扩展这个Support类。具体代码如下所示:

public class DAOSupport {
    
public final Connection getConnection() {
               
// 获得连接       
     }

    
public final void releaseConnection(Connection conn) {      
               
// 释放连接
     }

}
 

public class UserDAO extends DAOSupport {
    
private Connection conn = getConnection();
        
}

在以上的代码中,DAOSupport+UserDAO类就可以看作是一个Data Accessor,虽然仅仅是对获得和释放Connection的细节进行了封装,但是这样简单的分离都会令整个开发过程受益匪浅。
        上面的例子虽然实现了最简单的Data Accessor,但是事实上这样的Data Accessor还是太简陋了(原始社会的产品),毕竟你在UserDAO中操作数据表的话,还是得写SQL。好了,为了让这个Data Accessor更加名副其实,我们还要做进一步的抽象。通常对数据库表进行的操作不外乎CRUD,所以我们就可以在DAOSupport中增加相应的四个方法[1]

public List read(String table, String[] column) throws SQLException;
public void insert(String table, List rows) throws SQLException;
public void update(String table, Row selectedRow, Row updateRow) throws SQLException;
public void delete(String table, Row selectedRow) throws SQLException;

 其中Row是一个辅助类,用于表示数据库中的一行中的所有列或者某几列数据,可以通过一个HashMap来实现。上面定义的几个方法,实质上是要在方法体中实现SQL的自动构造,具体的实现就不在这里赘述了,有兴趣的朋友可以参考《数据访问模式——面向对象应用中的数据库交互》一书。 在增加了这四个方法之后,UserDAO中涉及数据访问的代码都可以通过调用这四个方法来完成了,完全脱离了具体的数据访问细节。当你为了优化查询的方法而修改read方法的时候,修改就会影响到所有的*DAO类,一处修改,处处受益。
        虽然我们通过抽象而建立起来的四个方法可以让我们逃避了SQL的困扰,但并非一劳永逸。细心的你一定会发现,read方法的参数仅是表名和列名,这样返回的纪录集将会是数据表中的所有行,因此,我们还是得增加一个参数,使得read方法更加实用。于是read方法就变成了这样:

public List read(String table, String[] column, HashMap conditions) throws SQLException;

在增加了conditions这样参数以后,read方法可以根据条件的界定获得相应的某一行了。功能增加了,随之而来的就是方法复杂度的增加,抽象过程也显得愈加困难。总之,Data Accessor最关键的在于逻辑操作的抽象,复杂度与功能之间的均衡。

[1] 代码参考了《数据访问模式——面向对象应用中的数据库交互》
分享到:
评论

相关推荐

    关于dao设计模式学习资料

    - **DataAccessor模式**:实现了数据访问和业务逻辑的分离。该模式通过提供一套抽象的数据访问接口,使得业务逻辑层不必直接处理具体的数据库操作(如SQL查询、更新等),从而简化了业务逻辑的实现。 - **Active...

    Smart-Net-Data-Accessor:2路外部SQL构建时数据访问器生成器库

    Smart.Data.Accessor .NET-.NET的数据访问器生成器库 这是什么? 构建时数据访问器生成器库。 支持2路SQL。 入门(.NET Core控制台应用程序) 安装 。 像这样创建数据访问器接口和模型类。 public class Data...

    java模式_DAO模式[汇编].pdf

    DAO(Data Access Object)设计模式是Java开发中用于处理数据访问的一种常见模式,它结合了Data Accessor模式和Active Domain Object模式。DAO模式的主要目的是为了分离数据访问逻辑和业务逻辑,提高代码的可读性、...

    Laravel开发-accessor

    在Laravel框架中,访问器(Accessor)是用于修改模型属性值的一种机制,它允许我们在获取数据时对其进行处理,而不改变原始数据存储。这在处理数据展示或格式化时非常有用。当我们需要根据多个条件来调整这个处理...

    android-data-folder-accessor:用于访问任何 android 应用程序的 datadata 文件夹内容的 Bash 脚本

    一个简单的 BASH 脚本,用于访问任何 android 应用程序的 /data/data 文件夹的内容。 使用此脚本,您可以访问任何 android 应用程序的内部数据库。 它基本上由一些基本的 adb 命令组成,这些命令允许您将内部存储...

    JavaScript数据实用程序库Datalib.zip

    Datalib 是一个 JavaScript 数据实用程序库。它提供用于数据加载、 类型推理、 常见统计和字符串的模板。包括:加载并解析数据文件(JSON, TopoJSON, CSV, TSV).统计摘要(均值、偏差、中位数、相关测量等).数据驱动...

    Cocoa design pattern

    访问器(Accessor)**:访问器模式提供了一种安全访问对象属性的方式。通常包括getter和setter方法,用于获取或设置对象的状态。 **3. 两阶段创建(Two-Stage Creation)**:在某些情况下,对象的初始化可能涉及多...

    访问器

    在编程领域,"访问器"(Accessor)是一种特殊的方法,用于获取或设置对象的属性值。访问器通常成对出现,分为getter和setter。getter方法用于获取属性的当前值,而setter方法则用于设置属性的新值。在面向对象编程中...

    PyPI 官网下载 | gcp_accessor-0.0.3-py3-none-any.whl

    `gcp_accessor`这个库很可能是Google Cloud Platform (GCP) 的一个访问接口或工具。GCP是谷歌提供的云服务,包含一系列的计算、存储、数据库和数据分析服务。`gcp_accessor`可能提供了与GCP交互的Python API,让...

    Hibernate教程

    2. **基于Data Class的持久层实现**:数据类作为业务类和持久层之间的桥梁,通常采用DAO模式,包括Domain Class和Data Accessor Class,分别代表业务对象和数据访问操作。 3. **基于现有持久层框架的实现**:使用如...

    Java之dao模式详解及代码示例

    DAO模式实际上包含了两个模式,一是Data Accessor(数据访问器),二是Data Object(数据对象),前者要解决如何访问数据的问题,而后者要解决的是如何用对象封装数据。 在信息系统的开发架构中,DAO模式主要应用在...

    设计模式-基于C#的工程化实现及扩展

    C#的泛型(Generic)特性使得装饰器模式更加灵活,而属性(Property)和访问器(Accessor)则在实现代理模式时大有裨益。 此外,资料可能还讨论了如何在面向服务(Service-Oriented)或微服务(Microservices)架构...

    你可以看到这个类对属性的存取方法(getter and setter method)使用了标准JavaBean命名约定,同时把类属性(field)的访问级别设成私有的(private)。这是推荐的设计,但并不是必须的。Hibernate也可以直接访问这些field,而使用访问方法(accessor method)的好处是提供了重构时的健壮性(robustness)。为了通过反射机制(Reflection)来实例化\

    Hibernate也可以直接访问这些field,而使用访问方法(accessor method)的好处是提供了重构时的健壮性(robustness)。为了通过反射机制(Reflection)来实例化这个类的对象,我们需要提供一个无参的构造器(no-...

    PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据

    本篇PHP杂谈将继续探讨关于数据重构的几个关键点,包括如何更好地组织和管理数据,以及何时和为何要进行这些改变。 首先,我们关注的是直接访问Field(字段)与通过函数(Accessor)访问Field的争论。访问者...

    包围盒and顶点访问器

    在OpenSceneGraph(OSG)这样的三维图形库中,顶点访问器允许程序员高效地读取和修改顶点数据,例如位置、颜色、法线等属性。通过顶点访问器,开发者可以方便地实现自定义的几何处理逻辑,如计算包围盒。 ...

    Core Data Tutorial

    在表格视图控制器中,需要创建并定义根视图控制器类(RootViewController),实现该类并编写相应的属性合成(Synthesize Properties)和访问方法(Accessor Methods),比如Core Location管理器的访问方法。...

    Python库 | ftrack_s3_accessor-0.1.5-py2.py3-none-any.whl

    资源分类:Python库 所属语言:Python 使用前提:需要解压 资源全名:ftrack_s3_accessor-0.1.5-py2.py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    不使用反射进行C#属性的运行时动态访问

    4. **多态和设计模式**:如果属性访问模式固定,可以考虑使用多态性,如工厂模式或策略模式,提前创建好具有特定行为的对象。这在面向对象设计中很常见,可以提高代码的可扩展性和性能。 5. **预编译的代理类...

    Access常用内置SQL函数

    Access内置的SQL函数极大地扩展了我们对数据的操作能力,特别是在处理日期时间、文本字符串以及进行聚合计算时。以下是对Access常用内置SQL函数的详细说明: 1. **CDate**: 这个函数用于将字符串转换为日期类型。...

Global site tag (gtag.js) - Google Analytics