[关闭]
@zhuanxu 2017-12-25T16:06:42.000000Z 字数 2044 阅读 2835

spring data jpa 系列教程一:orm常用设计模式

spring-data-jpa-系列教程


平时写业务代码中,最常见的事情可能就是数据库的CRUD操作了,可以这么负责任的说:互联网应用,本质就是在进行CRUD操作,唯一不同的就是业务条件不同,复杂度则来自于你要同时更新、查询的库表有多少。

刚开始入行的时候,我用的是php,当时自己简单的封装了一个Abstract Dao,然后基本每新建一个表就新建一个类就去继承这个Abstract Dao,如下所示:

  1. class User extends BaseDao{
  2. public $table = 'user';
  3. ...
  4. }
  5. abstract class BaseDao {
  6. insert();
  7. select();
  8. update();
  9. // delete //一般互联网应用都不会有delete操作
  10. }

但是这种做法带来的问题就是后期随着项目表的增加,会发现有太多的类了,而且这些类基本都只是去继承BaseDao,然后就是每个类都去要写一大推findByXXX的接口,那有没有什么办法能一劳永逸呢?避免这种枯燥的代码呢?

先别着急解决方法,我们先来来点理论基础的,看下常见的orm设计模式。

Row Data Gateway

Row Data Gateway
一个对象扮演的角色就像是数据库中单行记录的网关(Gateway)

每个对象对应数据库中的一行:

使用

底层实现


Table Data Gateway

Table Data Gateway
扮演着数据库表的网关角色(Gateway),一个对象处理了表中所有的行记录.

此处DAO 实现了 CURD 操作,读一般会比较复杂,是一系列 Finders
insert方法

update方法

Finder方法

使用魔术方法 __call() 来实现这些魔术般的 finders

http://www.php.net/manual/en/language.oop5.overloading.php#object.call.

Active Record

Active Record
封装了表中的单行记录,除此之外加上了领域逻辑.

Active Record = Row Data Gateway + Domain Logic

我们会直接将一些领域逻辑写到dao中。

Data Mapper

Data Mapper 让 dao 和业务逻辑彼此独立,通过 Data Mapper 来将内存中的对象和数据库中的记录联系起来。
Data Mapper
将内存中的数据映射到数据库中,同时保持着彼此之间的解耦。

Identity Map

Identity Map 在 Data Mapper 之上更进了一步,不仅维护了映射关系,而且对数据库进行了缓存,保证同一个对象的请求不会重复去数据库中读取,减少io,同时保证对象发生变化后,能同步到数据库中。
Identity Map
保证每个对象只会从数据库中加载一次,一旦加载进来,将其保存到一个 map 中

Object Relational Mapping

介绍完上面的常用设计模式后,我们来看一个概念:ORM,对象关系映射。
ORM 一般认为是实现上面各种设计模式的一个工具,并且能很方便的处理对象之间的关系,而常见的对象关系有:

有了orm之后,在更进一步的Domain-Driven Design中,orm可以说是再进一步,在 ddd 中常见的几个概念有:

Entity
Value Object

为了我们方便的处理Entity,就出现了Repository。

Repository Pattern


Repository 协调了领域对象和数据映射层的关系,扮演着内存中领域对象集合( in-memory domain object collection)的角色。

对象可以被添加进 Repository,同样的也能从 Repository 中移除,从这个角度讲,Repository 有点类似于集合的概念,其内部封装了对象和数据库记录之间的映射关系,Repository 提供了 persistence 的一个更面向对象的视角。

Repository 同时很好的解决了领域对象和数据映射层之间的耦合关系,充分的分离的关注点,领域对象和数据映射层可以独自的开发,演化。

Specification Pattern

在 Repository 中,我们不得不面对各种各样的查询条件,于是就有了 Specification 模式,帮助我们解决查询条件多的问题:

Specification pattern 可以将业务规则建模为独立的对象,其主要思想是关注一个对象的问题,可以通过isSatisfiedBy()来回答:

Repository ♥ Specification

将 Repository ♥ Specification 两者组合起来:



在业务层复用 specifications:

这是 jpa 的第一篇,你的鼓励是我继续写下去的动力,期待我们共同进步。
这个时代,每个人都是超级个体!关注我,一起成长!

参考

https://github.com/willdurand-edu/php-slides/blob/master/src/common/09_databases.md

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注