Martin fowler几年前曾经非常推崇ORM(对象/关系数据库映射框架),特别是Hibernate和Ruby的Active Record,现在他面对大家越来越多对ORM责难和怀疑。他写了这篇新的文章:ORM的厌倦(OrmHate),下面大概谈谈他这篇文章大意。
首先,MF为ORM带来的复杂性做了辩解,对象和关系数据库存在天然阻抗,试图调和总是带来复杂性。他也认为:The object/relational mapping problem is hard,试图在对象和关系数据库之间进行映射是很难的,因为你需要处理两种不同角度视图中的数据,一个是关系数据库中,还有一个是内存中in-memory,这两者常常是由ORM实现,这里一点和对象没有关系,准确地说,ORM实际是在进行内存(in-memeory)和关系数据库之间映射,内存数据结构比关系模型要更灵活,大多数人更愿意使用这种内存数据结构,然后将其再保存持久到数据库中。
这种映射要比我们想象复杂得多,因为你一旦在内存改变数据结构,就必须映射同步到另外一边,如果有多个操作同时并行修改数据库就更复杂,ORM得处理这种并发,这种情况下你不能依赖事务机制,因为当你摆弄内存中数据,你是不能hold住事务的(通常通过数据库锁hold住)。
那么有没有ORM的替代呢?
MF提出两个解决方案:MF认为Hibernate 和 Active Record 已经是一个膨胀化软件,他看到很多人开始做自己系统的ORM,这是非常厉害的,但是他们没有意识到已经掉入泥潭,MF认为对象和关系数据库的映射如同计算机科学中的越战。
虽然很多ORM框架如 iBatis, Hibernate, 和 Active Record做了很多努力解决了很多问题,但是关键问题还是存在,ORM能够解决80%-90%的问题,但是剩余的问题就必须理解ORM和关系数据库内部工作机制才能解决。
MF认为这实际就是正确使用ORM的方式,他以Ruby中Active Record创造者David Heinemeier Hansson的话为例子,ORM帮助你处理掉了大部分无聊垃圾代码,但也提供了一个管道和沙井,让你直接处理SQL语句。
但是人们常常抱怨,为了使自己的对象模型更适合ORM,屈就ORM,只能变得更加具有关系化,MF认为这是使用关系数据库的必然结果,你要买使你的内存模型更加关系化,要么复杂化你的映射代码,为了简化你的对象和关系数据库映射,你最好哦让你的领域模型更加具有关系化,但是并不意味着你得按关系模型设计领域模型。
ORM是复杂的,因为它得处理双向映射,如果只有单向映射,问题复杂性也许就会解决,前提是你感觉SQL不复杂,这就是CQRS(读写分离)。
MF提出避免ORM这些复杂性的两个替代解决方案:
1.使用内存关系模型,也就是直接使用SQL。
2.干脆不使用关系数据库,直接使用NoSQL。
个人认为这两种方案比较极端,还是CQRS方案更好,实际可以通过内存中对象化的领域模型来屏蔽掉SQL或NoSQL,无论是SQL或NoSQL,都是领域对象的持久化,当然批量查询读取专门走另外一条线,结合NoSQL+Hadoop可以实现大数据分析。
MF提出这两种解决方案,其实还是不想否定ORM作用,将ORM复杂性归结为关系模型,其实纯粹的关系模式是很干净简单的,复杂就在于你把对象和关系搞在一起。
================================
ORM框架有无必要?
Eric Evans关于技术如何影响DDD的会话
http://www.infoq.com/interviews/Technology-Influences-DDD#
1.NoSQL和关系数据库一样,只是对象的一种持久方式。
关系数据库是最伟大的发明之一,关系模型也是看待问题最强大的工具,而面向对象也是一种看待问题的强大工具,但是如果你将两者捆绑在一起,实际是损毁它们的优点。
对象概念其实很长时间已经被J2EE等重量框架摧残了很长时间,而且更被阴险的映射到关系数据库上。
2.Domain Events或Event Sourcing实际是从面向函数角度去思考,面向函数语言的思维方式是一种流思考方式。值对象在面向函数中很自然,实际就是数据结构。
3.领域对象应该生存在内存中, 如果我们有一个巨大的内存存储,对象就能够成功生存,但是当你和关系数据库进行绑定等,你就会遭遇彼此的不匹配,如果你要得到快速的,好的 非常嫩脆的对象,就应该将他们放入内存中。
4.DDD最大特点是统一语言。
原文:ORM HATE
http://martinfowler.com/bliki/OrmHate.html