数据源层的作用是与应用需要的基础设施的不同部分进行通信。问题主要是和数据库的会话。1.架构模式架构模式要解决的问题是驱动领域逻辑访问数据库的方式。把sql访问从领域逻辑中分离出来,并把它放到独立的类中,是明智之举。有一种方法能很好的组织这些类:让它们以数据库中的表结构为基础,这样,每一个数据库表对应一个类,这些类为数据表建立了一个入口。使用入口的方式有2种:1.行数据入口,为查询语句返回的每一行产生一个它的实例;2.表数据入口,使用记录集对应数据库中的每个表。清晰的sql和领域逻辑分离是有益的。在简单应用中,领域模型是一种和数据库结构相当一致的简单结构,对应每个数据库表都有一个领域类。这种领域对象的业务逻辑复杂度通常适中。在这种情况下,有必要让每个领域对象负责数据库的存储过程,这也是活动记录。从另外一个角度来考虑活动记录,就是从行数据入口开始,然后把领域逻辑加入到类中,特别是在从多个事务脚本中发现重复代码的时候。在这种情况下,入口增加的间接性提供的价值不大。随着领域逻辑变得更加复杂,它就慢慢转变成一个大的领域模型,简单的活动记录开始不能满足需求了。领域类和表的一一对应匹配也开始随着把领域逻辑放入更小的类而失效。关系数据库无法处理继承,因此使用策略模式和其他轻巧的面向对象模式非常困难。一种更好的办法是领域模型和数据库完全独立,可以让间接层完成领域对象和数据库表之间的映射。这个数据映射器处理数据库和领域模型之间的所有存取操作,并允许双方都能独立变化。这是数据库映射架构中最复杂的架构,但它的好处是把两个层完全独立了。不推荐把入口用作领域模型的首选持久化机制。如果领域逻辑比较简单并且类和表十分一致,使用活动记录就够了。如果领域逻辑比较复杂,数据映射器才是需要的。2.行为问题所谓行为问题,就是如何让各种对象从数据库中读取出来以及存到数据库中。如果加载了一些对象到内存并且进行了修改,就必须跟踪每个修改过的对象,并且保证他们写回数据库中。如果仅仅是加载了2条,这是很容易的。一旦加载的对象越来越多,这就不再是一件容易的事情,尤其是在创建了某些行的同时,还修改了其他行,这是由于在修改引用它们的行之前要获得新行的主键。这问题虽小,但不容易解决。因为要读取对象并修改它们,所以就必须保证正在使用的数据库状态的一致性。如果读取了某些对象,重要的是要保证读取必须是独占的,也就是说,没有其他进程在读取的同时修改这些对象。否则,就可能在对象中得到不一致或无效的数据,这就是同步问题。有一种专门解决上述问题的模式就是工作单元。工作单元会跟踪所有从数据库中读取的对象以及所有以任何形式修改过的对象。它同样负责将更新提交到数据库中。应用程序的编程人员将工作交给工作单元,而不是直接调用明确的保存方法。工作单元排列好对数据库的操作顺序,把所有复杂的提交处理放在一起。当与数据库的交互比较复杂的时候,工作单元是一个必要的模式。可以这样理解工作单元,它是一个对象,充当数据库映射的控制器。在没有工作单元的情况下,一般都是由领域层充当控制器,决定何时读写数据库。工作单元就是来源于把数据库映射控制器的行为分解到它自己的对象中。加载对象时,必须小心避免把同一个对象加载两次,否则,内存中就有2个对象和同一个数据库行对应。对它们进行更新就乱套了。为了解决这个问题,可以在标识映射里记录读取的每一行。每次读入数据时,必须到标识映射里去检查一下是否已经存在。如果该数据已经加载了,可以返回一个对它的引用。这样,所有的更新操作就可以正确的组织好。还可以得到一些好处,比如可以避免一些数据库调用,因为标识映射就像一个数据库高速缓存。延迟加载的主要思想是拥有一个对象的占位符,而不是实际对象。当且仅当想要通过链接访问的时候,才会真的去数据库读取实际对象。3.读取数据读取数据的时候,可以把读取数据的方法看作是一个查找器,它通过一个方法结构的接口来隐藏sql查询语句。因此,可以使用诸如find(id)findForCustomer(customer)这样的方法。在什么地方放置查找器方法是使用的接口模式决定的。如果数据库交互类是基于表的,也就是说对于数据库中的每个表都有一个类的实例与之对应,那么就能把插入和更新操作也捆绑在查找器方法中。如果交互类是基于数据行的,也就是说对于数据库中的每一行都有一个列的实例与之对应,这种情况就不行了。使用查找器方法时要注意的是:这些查找器方法工作在数据库状态下而不是对象状态下。尽量一次读回多行。避免多次进入是数据库的方法是使用联接(join),这样就可以通过一次查询返回多个表。得到的记录集可能看起来比较奇怪,但确实能加速查询速度。在这种情况下,可以建立一个入口来得到互相联接的表数据,或者是通过一个数据映射器用一次调用加载更多领域对象。4.结构映射模式当人们谈到对象---关系映射的时候,多半说的是结构映射模式,在内存对象与数据库表的映射中会用到它们。1.关系的映射这里的关键问题在于对象和关系处理连接的方法不同,这会带来2个问题。首先,表现方法不同。对象是通过在运行时中保存引用的方式来处理连接的。关系数据库则是通过创建到另外一个表的键值来处理连接。其次,对象可以很容易通过集合来表示多个引用,而规范化则要求所有的关系连接都必须是单值的。这就导致对象和表之间的数据结构颠倒了。解决这种表现问题的方法是:通过对象中的一个标识域来保持每个对象的关系特性,并且通过查找这些值来保持对象引用和关系键之间的互相映射。从硬盘读取数据的时候,使用标识映射作为从关系键到对象的查找表。每次使用表中的外键,都用外键映射来得到合适的对象间引用。如果标识映射中没有该键值,就需要到数据库中读取它或者使用延迟加载。每次存储对象时,就可以用正确的键值把它存储到行中,用目标对象的id域替换任意的对象间引用。在这个基础上,集合的处理需要更复杂的外键映射版本。如果对象包含一个集合,则必须构造一个新的查询来找到所有与源对象的id相关的行。创建每个返回的对象并加入到集合中。对这个集合的保存包括:保存其中的每一个对象,并且保证它拥有一个到源对象的外键。这样非常混乱,尤其是当要检测对象加入或移除这个集合的时候。当你熟悉了以后,你会发现这是重复性问题,这也是为什么某些基于元数据的方法会明显导致系统规模更大了。如果集合中的对象不在集合拥有的范围之外使用,就可以使用依赖映射来简化映射。多对多的关系情况不同,这时两边都存在集合。关系数据库不能解决这个问题,因此需要使用关联表映射来创建一个新的关系表,仅仅是为了解决多对多的关联问题。使用集合的时候,通常需要依赖集合中的排序。在面向对象语言中,通常使用数组或者列表这样的有序集合。实际上还可以简化测试的难度。然后,在保存到关系数据库中的时候想要维持一个绝对有序的集合是非常困难的。因此,有必要考虑使用无需集来存储集合。另外一种办法是无论何时进行集合查询都要按照某种分类顺序,这样代价很高。标识域用来把对象间引用变为外键,但并不是所有的对象关系都需要这种方法持久化。一些小的值对象(比如日期和钱)显然不应该描述成数据库中它们自己的表。取而代之的是,取出值对象中所有的域,并以嵌入值方式把它们嵌入到关联对象中。还可以在更大规模上做类似工作,此时,可以通过序列化LOB将一组对象存储为表中的单个列。LOB代表'大对象'(large object),它可以是二进制的,也可以是文本的。将一组对象序列化为xml文档,对于层次化对象结构显然可以采取的方法。这样可以通过一次读取获得一整串互相关联的小对象。通常,数据库对于小的高度互连对象执行起来很低效,因为需要花费大量时间来进行许多很小的数据库调用。2.继承上面说的'层次',大多是'组合层次',比如传统的关系系统难以处理的部件树。还有另外一种 也会使得关系系统头疼的层次:通过继承关系互相连接的类层次。因为在sql里面没有用于继承的标准方法,所以我们必须再用到一个映射。对于任何的继承结构,一般都有3种选择。可以为一个层次中的所有类建一个表,即单表继承;也可以为每个具体的类建一个表,即具体表继承;或者为整个层次中的每个类建一个表:类表继承。在数据结构复制和访问速度之间必须进行权衡。类表继承是类和表之间最简单的关系,但是它需要多个连接(join)操作来载入一个对象,这样通常损失了性能。具体表继承避免了连接操作,允许从一个表中取得一个对象,但是改变起来比较困难。对超类的任何改变都不得不改变所有的表(还有映射代码)。改变层次结构自身会带来更大的改变。缺乏超类表也能使得主键管理十分可怕,引用完整性也有问题,尽管它能减少超类表中的锁争用。而在某些数据库中,单表继承最大的弊端就是浪费了空间,因为每一行都必须为每种可能的子类保留一些列,这就导致很多空列。然而,许多数据库都能很好的压缩浪费的表空间。单表继承的另一个问题在于它的大小将成为访问的瓶颈。它的最大的好处是把所有的内容都放在一起,这样修改起来很容易并且避免了连接操作。这3个选择并不是互相排斥的,在一个层次中可以混合几个模式。举个例子,可以用单表继承把几个类放在一起并且使用类表继承来处理一些特殊情况。当然,混合模式会增加复杂性。比较倾向单表继承,因为它比较容易实现,并且易于重构。5.建立映射映射到数据库,一般会碰到3种情况:1.自己选择数据库方案2.不得不映射到一个现有数据库方案,这个方案不能改变3.不得不映射到一个现有的数据库方案,但这个方案是可以考虑改变的。最简单的情况是自己选择数据库方案,并且不用迁就领域逻辑的复杂性,最终得到的结果是一个事务脚本或者表模块设计。在这种情况下,可以使用经典的数据库设计技术围绕数据来设计表,使用行数据入口把sql从领域逻辑中删除。如果使用领域模型,应该小心那种看上去像数据库设计的设计。在这种情况下,建立领域模型时不用理会数据库,这样可以简化领域逻辑。把数据库设计看做是一种持久化对数数据的方法。数据映射器非常灵活,也带来了复杂性。如果数据库设计和领域模型同构有意义,可以考虑使用活动记录来代替。当已经存在一个数据库方案的时候,选择很相似,但过程却有点不同。对于简单的领域逻辑,可以建造行数据入口或表数据入口来模拟数据库,并在此之上构建领域逻辑。如果领域逻辑更复杂一些,将需要一个领域模型,而这个模型很可能和数据库设计不匹配。因此,应该逐步建立领域模型并包括数据映射器,把数据保存到现有的数据库中。双向映射:有时候,会遇到这种情况:同样的一种数据却需要从不止一个数据源上取出来。可能有多个数据库保存相同的数据,只是由于某种复制和黏贴的重用会导致在数据库方案上的一些细微区别。另一种可能是使用不同的存储机制,有时是数据库,有时是消息。也可能是把类似的数据同时从xml消息,cics事务和关系白鸥中抽取出来。最简单的选择是建立多个映射层,每个数据源一个。然而,如果数据非常类似的话,就会导致过多的复制。在这种情况下,可以考虑两步映射策略。第一步把数据从内存方案中转化到逻辑数据存储方案。设计逻辑数据存储方案是用来最大化数据源格式的相似之处。第二步映射从逻辑数据存储方案到实际物理存储方案。6.使用元数据重复代码是设计上有问题的一个标志。可以通过委托和继承分解出通用行为,但还有一种更成熟的方法是使用元数据映射。元数据映射基于把映射浓缩到元数据文件的方法。元数据文件详细描述了数据库中的列如何映射到对象的域。这里的关键在于:一旦有了元数据,就可以通过代码生成或者反射编程来避免重复性代码。使用元数据使我们可以用少量的元数据表达很多含义。当使用元数据映射的时候,有必要构造对内存对象的查询。一个查询对象允许根据内存对象和数据来构造查询,在这种方式下,开发者不需要知道sql或关系数据库方案的细节。查询对象可以使用元数据映射把基于对象域的表达式翻译到对应的sql。一直使用这种方法就可以建立一个资源库,它能很大程度上从视图隐藏数据库。任何到数据库的查询都可以做出资源库基础上的查询对象,并且开发者不用分辨对象是从内存还是从数据库找回。7.数据库连接大多数数据库接口依赖于某些数据库连接对象,它们就好像应用程序代码和数据库之间的连接桥梁。通常,一个连接必须在能执行针对数据库的命令之前就打开。实际上,经常需要一个显式连接来建立和执行命令。在命令的整个执行过程中,该连接必须是打开的。查询的结果将返回一个记录集。在很多环境中,建立连接的开销相当大,这就需要建立一个连接池。在这种情况下,开发者向连接池请求一个连接并完成以后释放,而需要即时创建和关闭。最常见的建议就是用一个到连接池或者连接管理器的调用,显式得到一个连接,并且通过它来执行数据库命令。一旦执行完了,立即把它关闭。这个建议带来两个问题:首先,保证在任何需要的地方都能得到一个连接;其次,保证不会再最后忘记关闭它。和连接差不多,内存也是一种在不用的时候需要释放的资源。现代环境提供了自动的内存管理和垃圾回收机制,因此保证连接关闭的一种方法就是使用垃圾回收器。在这种情况下,连接自身或引用这个连接对象会在垃圾回收期间关闭连接。

https://juejin.im/post/5c4b1ee6f265da612e28fb83

3.企业应用架构模式 --- 映射到关系数据库相关推荐

  1. [201004][企业应用架构模式][王怀民][周斌][译]

    [201004][企业应用架构模式][王怀民][周斌][译] 模式列表 引言 0.1 架构 0.2 企业应用 0.3 企业应用的种类 0.4 关于性能的考虑 0.5 模式 0.5.1 模式的结构 0. ...

  2. 软件开发大师谈企业应用架构模式

    <企业应用架构模式(英文版)> --作者:Martin Fowler 多年来,Martin Fowler --这位享誉世界的软件开发大师--见证了许多企业级应用项目.这些项目通常都包含相似 ...

  3. 企业应用架构模式-30天阅读计划

    构建计算机系统并非易事.随着系统复杂性的增大,构建相应软件的难度将呈指数增大. 同其他行业一样,我们只有在不断的学习中进步,从成功经验中学习,从失败教训中学习,才有望克服这些困难. 这本书的内容就是这 ...

  4. 《企业应用架构模式》30天阅读计划

    构建计算机系统并非易事.随着系统复杂性的增大,构建相应软件的难度将呈指数增大. 同其他行业一样,我们只有在不断的学习中进步,从成功经验中学习,从失败教训中学习,才有望克服这些困难. 这本书的内容就是这 ...

  5. 图书推荐5:《企业应用架构模式》

    文章目录 基本介绍 推荐理由 总结 延续 基本介绍 书名 企业应用架构模式 作者 (美)Martin Fower 译者 王怀民 周斌 出版社 机械工业出版社 出版时间 2004年12月 页数 363 ...

  6. 企业应用架构模式笔记

    1 企业应用模式概述 1.1 企业应用的模式 企业应用领域要解决的问题在某些方面要比做一个工具软件.或者一个电信通信软件等复杂的得多,比如纷杂的企业数据,各具特色的业务规则,变化莫测的用户需求.因此企 ...

  7. 企业应用架构模式学习笔记

    1.概述 2.分层 表现逻辑处理用户与软件间的交互.表现层的主要职责是向用户显示信息并把从用户那里获取的信息解释成领域层或数据源层上的各种动作. 数据源逻辑主要关注与其他系统的交互,这些系统将代表应用 ...

  8. 第十三天-企业应用架构模式-对象-关系元数据映射模式

    元数据映射 (Metadata Mapping) 查询对象 (Query Object) 资源库 (Repository)

  9. 第八天-《企业应用架构模式》-通盘考虑

    思考三个方面的技术实践:持续集成.驱动测试开发和重构 1. 从领域层开始 1)事务脚本模式最简单,适合于在关系数据库之上构建:领域模型需要非常专业的技术,还有鱼数据库的连接:表模块模式折中,在.Net ...

  10. 重温经典之《企业应用架构模式》——.NET中的架构模式运用 (Base Patterns 1)

    今天看看几个基本模式,这包括Gateway模式,Mapper模式,LayerSupertype模式和Separated Interface模式. 在这本书的最后一章,Martin Fowler放了一大 ...

最新文章

  1. 针对七牛含有特殊字符的文件名,对特殊字符编码处理
  2. 素数 乘法表 闰年
  3. 学习python的基础是什么_学python需要什么基础
  4. MonoRail学习笔记十一:页面控件的填充和验证
  5. idea springboot 发布webservice 发布服务_阿里云发布 Spring Boot 新脚手架,真香
  6. STL源码剖析 hashtable
  7. leetcode报错runtime error: reference binding to null pointer of type ‘std::vector<std::__cxx11::basic_
  8. 三色标记原理,我给应聘者问懵了...
  9. 求向量的垂线_高考数学填空题如何快速求直线关于直线对称的直线方程
  10. tp3.2 页面trace使用
  11. java socket第三方库_Java基于Socket实现HTTP下载客户端
  12. 【原】oracle11g 客户端安装检测失败问题
  13. 钉钉日志范文100篇_钉钉工作日记(模板一)
  14. 贪吃蛇c语言代码 vc++6.0,贪吃蛇代码-C语言版-VC++6.0
  15. php实现简易聊天室
  16. 终级免杀之PcShare Vs KV2006
  17. SQL刷题:排名的问题
  18. 【WebStorm学生认证】如何用学生邮箱进行JetBrains学生认证
  19. 深入理解5G SSB协议
  20. c语言编程矩阵鞍点函数,c语言 任意输入一个3×3的矩阵,用函数实现求上三角矩阵并输出。...

热门文章

  1. [redis]redis五种数据类型和应用场景
  2. #Leetcode# 141. Linked List Cycle
  3. 中文词向量论文综述(三)
  4. wenbao与最短路(Floyd)
  5. Java--UI--弹出对话框
  6. 劲牌——业务流程管理方案
  7. springmvc结合json向后台传送数据(get、post)
  8. Codeforces Round #173 (Div. 2)
  9. Java对象的强引用、软引用、弱引用和虚引用 笔记
  10. 了解一个百万级 PHP 网站的架构