本文内容

  • 什么是持久层
  • 为什么要持久层
  • 持久层框架

 

什么是持久层


理解持久层,可以看它的英文——Persistence Layer。“持久(Persistence)”和“层(Layer)”。在我看来,“持久”更多涉及的是底层结构,而“层”更多涉及的是逻辑层面、软件设计。
在计算机早期,数据的存储只能在内存里,没有外部介质可以长期保持数据或代码,因此不能在需要时读取或是执行。看看现在,你几百个G的硬盘上都是什么,各种软件、各种照片、各种MP3……再看看数据库领域,如何存储、持久化海量数据,不仅要持久化数据,而且还要组织它们。这就是持久(化)。
“层”是什么概念?既然数据已经被持久化到介质上(无论这个介质是什么,磁盘也好,文件也罢,毕竟我们经过文件形式的数据库),那接下来的问题,也是最终问题:应用程序如何使用这些数据?通常采用三层架构的应用程序——表现层、业务逻辑层和数据库访问层。让业务逻辑层直接访问数据库库层,或是在业务逻辑层与数据库层之间再增加一层——持久层,让持久层去访问数据库层,而业务逻辑层访问持久层。这样,将数据的使用(业务逻辑层)与数据的实体(数据库)分离。

增加持久层的好处,在我看来,如果操作数据库的数据,就像操作程序中的类(类的属性)一样,那就再方便不过了。

 

为什么要持久层


先简单说明一下三层架构和它们的职责。在典型的三层架构中,对其职责的划分并没有一个统一的规范,综合现有的成功实践和 .NET 平台的特点,将三层架构的职责划分如下:

  • 数据访问层——负责与数据源(数据库)的交互,即数据的增删改和查询。不负责验证数据的正确性和有效性,不负责业务逻辑。无需知道数据的用途。
  • 业务逻辑层——负责系统领域业务的处理,如逻辑性数据的生成、处理及转换。负责验证输入数据的正确性和有效性,不负责验证输出的数据(如用户数据);不负责数据的呈现。
  • 表示层——负责接收用户的输入、并将输出呈现给用户以及访问安全性验证。负责验证输入和输出数据的正确性和有效性,呈现(式样);不负责在发生错误时的异常。

总而言之,表示层负责输入数据的验证,以及输出数据的验证,因为要呈现数据给用户;业务逻辑层只负责处理业务数据,并在发生错误时抛出异常信息;数据库层只负责提供数据,供业务逻辑层使用。

虽说业务逻辑层不负责输入数据的验证(也就是说,不应该承担过重的数据验证功能),因为这个应该在表示层完成,但也应该至少提供基本的验证,比如如果输入为空(长度为0)、NULL等等,则执行业务,否则直接返回。数据库层亦然。

场景

假设有这样的需求,分页显示文章列表:

  • 显示文章的标题、作者和发布时间。
  • 如果文章标题超过15个汉字,则截断显示,以“…”表示。
  • 如果是作者本人,则需在文章后边显示“编辑”和“删除”按钮。

接下来的问题是——在三层层架构中,如何各自的分配职责?

分析
  • 对于需求1,业务对象应该返回给表现层一个文章的实体对象。文章的实体对象是一个集合的数据结构,这个对象有很多实现,比如 DataTable,json,ArrayList,甚至XML等等。
  • 文章的实体对象至少应该包含“文章标题”、“作者”、“发布时间”等信息。文章的实体对象可以包含“作者”的详细信息(注册信息),也可以只是简单的信息。
  • 对于需求2,仅仅是需求1的显示问题,与数据本身毫无关系。
  • 对于需求3,要知道文章是否属于当前用户。这要根据文章实体对象中的“作者”信息,与 session["username"] 进行判断。
职责分配
  • 分配给业务逻辑层

文章的列表,无论是默认的显示,还是有条件的显示,业务逻辑层应该根据用户需求,从数据库中返回相应的文章列表,并形成一定的数据结构。

  • 分配给数据库访问层

仅仅是根据业务逻辑层的需求,从数据库中返回相应的文章列表。

  • 分配给表现层

表现层应该根据业务逻辑层返回的文章列表,完成数据呈现,包括显示文章标题、作者和发布时间,以及文章标题的截取。

对于需求3,既可以交给业务逻辑层,也可以交给表现层来做。我个人更倾向在业务逻辑层来做,因为后台代码便于维护,根据文章权限设置按钮是否可见。

 

更具体点,一般的步骤如下:

  • 用户输入文章检索/过滤条件(也可以不输入,提供默认文章列表),表现层验证用户输入是否有效,如果无效,给出提示;否则,提交给业务逻辑层;
  • 业务逻辑层根据用户输入(也可以没输入,提供默认检索/过滤),创建 SQL 语句;
  • 将生成的 SQL 语句,提交给数据访问层;
  • 数据访问层建立数据库连接,并执行SQL,把文章列表返回给业务逻辑层(可以分页获取)。此时关闭与数据库的连接,并释放资源;
  • 业务逻辑层把数据库访问层返回的文章列表,提交给表现层。同时负责“编辑”和“删除”按钮可见性;
  • 表现层根据业务逻辑层返回的文章列表,按照式样呈现给用户。

 

关系型数据库中的数据都是以数据行进行存取的,而程序运行却是按对象处理,目前,大部分数据库驱动技术,如 ADO.NET、JDBC、ODBC 等,均是以行集的结果集一条条进行处理的。因此,为解决这个问题,就出现 ORM (Object / Relational Mapper)技术——对象与关系数据之间的映射技术。

比如,要完成一个用户购物打折的程序,用 ORM 思想如下:

double amount)
{
    // 根据客户ID获得客户记录
    Customer customer = CustomerManager.getCustomer(custmerid); 
    // 根据客户等级获得打折规则
    Promotion promotion = PromotionManager.getPromotion(customer.getLevel()); 
    // 累积客户总消费额,并保存累计结果
    customer.setSumAmount(customer.getSumAmount().add(amount); 
    CustomerManager.save(customer); 
    // 返回打折后的金额
    return amount.multiply(protomtion.getRatio()); 
}

相关文章: