企业应用架构模式笔记--第三章(映射到关系数据库)
数据源层的作用:
与应用需要的基础设施的不同部分进行通信。问题主要是和数据库的会话。
3.1架构模式
架构模式主要解决的问题是驱动领域逻辑访问数据库的方式。此时的选择对于设计影响深远而且难以重构。
模式一:将SQL访问从领域逻辑中分离出来
为了使用适合程序开发语言的机制来访问数据更方便,很多技术把SQL语句嵌入到程序设计中。
但是当数据库管理员(DBA)也想得到访问数据库SQL语句,这样DBA才能理解怎样是最好的调整和组织索引。
而解决这样的问题的方法就是把SQL访问从领域逻辑中分离出来。
为了达到这样的实现,一种解决的方法是:
以数据库中的表结构为基础,这样每个表对应与一个类,这些类为数据表建立一个入口。应用程序的其它部分不用去了解
任何与SQL相关的事情。
使用入口的方法有两种:
1.为查询语句返回的每一行产生一个实例
人员类 |
Lastname Firstname numberofDependents |
Insert Delete Update |
2.以数据集作为一个单位产生实例
人员类 |
Find(id):RecodSet findWithLastName(string):RecodSet Update(id,lastname,firstname,numberofDepartment) Delete(id) |
表数据入口对每个表有一个实例
对于简单的程序,也建议一种入口方式,这样的好处是清晰的SQL和领域逻辑分离。
领域模型:
在简单的应用中,领域模型是一种和数据库结构相当一直的简单结构,对于每个数据库表都有一个领域类。
而这种领域对象的业务逻辑复杂度通常适中。而这样的情况下,有必要让每个领域对象负责数据库的存取过程。
如图:
Customer |
Load(ResultSet) Delete Insert Update checkCredit |
缺点:
入口增加的间接性提供的价值不大。随着领域逻辑变得复杂,它就慢慢转变成一个大的领域模型,简单的活动记录开始不能满足要求了
领域类和表是一对一匹配也开始随着把领域逻辑放入更小的类而失效。关系数据库无法处理继承,因此使用策略模式和其它轻巧的面向
对象模式非常困难。
解决方法:
把领域模型和数据库完全的独立。可以让间接层完成领域对象和数据库表之间的映射。
Customer(类)--->Customer Mapper--->Customer(表)
3.2行为问题
所以行为问题,就是如何让各种对象从数据库中读取出来以及存到数据库中。
工作单元:解决从数据库中读取数据后的跟踪问题
工作单元会跟踪所有从数据库中读取对象以及所有以任何形式修改过的对象。它同样负责将更新提交到数据库。
应用程序的编程人员把工作交给工作单元,而不是直接调用明确的保存方法。
工作单元排列好对数据库操作的顺序,把所有复杂的提交放在一起。
3.3读取数据
1.尽量一次读回多行数据
2.避免多次进入数据库的方法使用链接(Join)--这样可以通过一次查询返回多张表
3.4结构映射模式
关系的映射
对象和关系处理连接的方法不同
1.表现方法不同
对象是通过运行时(内存管理环境或内存地址)中保存引用的方式来处理连接的
关系数据库则是通过创建到另外一个表的键值来处理连接的。
2.对象很容易通过集合来表示多个引用,而规范化则要求所有的关系连接都是单值的。而这样就倒置了对象和表之间的数据
结构颠倒了。
解决方法是:通过对象中的一个标识域来保持每个对象的关系特性,并且通过查找这些值来保持引用对象和关系对象之间的映射。
其实应该就是通过外键映射来作为从关系建到对象的查找表。
关于大对象
LOB表示大对象,将一组对象序列化为XML文档,对于层次化对象结构是显然可以采用的方法。这样就可以通过一次读取获得
一整串互相关联的小对象。
通常,序列化LOB对于用来组成应用程序部分相对独立对象群而言是最好的。
继承:
1.单表继承--一个层次中的所有类建立表
缺点:浪费空间,会存在很多空列。而且表的大小也会成为访问的瓶颈。
优点:把所有的字段都放到一起,访问起来很方便,而且避免了很多的连接操作。
2.具体继承--为每个具体类建立一个表
缺点:避免了连接操作,允许从一个表中获取一个对象,但是一旦超类做任何改变,所有的子表都要做改变。
但是如果没有超类,将使管理主键称为很可怕的事情
3.类表继承--为一个层次中的每个类建立一个表。
缺点:需要连接多个连接操作来载入对象,这样通常损失性能