设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 开源资讯 查看内容

Spring Data与MongoDB:不协调的设计

2013-11-15 09:53| 发布者: joejoe0332| 查看: 3554| 评论: 0|原作者: 张龙|来自: InfoQ

摘要:   MongoDB是一款非常知名的NoSQL文档数据库,而Spring则是Java领域著名的开源框架。除了构成Spring核心的IoC与AOP之外,Spring也有大量应用于各个不同领域的子框架,其中Spring Data就是专门针对数据处理的一个子 ...

  MongoDB是一款非常知名的NoSQL文档数据库,而Spring则是Java领域著名的开源框架。除了构成Spring核心的IoC与AOP之外,Spring也有大量应用于各个不同领域的子框架,其中Spring Data就是专门针对数据处理的一个子项目。在Spring Data下有Spring Data JPASpring Data MongoDBSpring Data Redis等子项目,从名字就可以看出来这些子项目所针对的目标。其中,Spring Data MongoDB是专门针对MongoDB的一个子项目,旨在通过Spring的方式来操纵MongoDB,那么这种集成是简化了开发还是阻碍了开发呢?


  Prashant DevaChronon的 创始人与CTO。他是一位持续创业者,还创办了Placid Systems、AntlrStudio及Virtual Ant。作为一名极客,Deva喜欢尝试各种新鲜技术,在使用了Spring Data MongoDB一段时间后,他认为这个框架在设计上存在着严重的问题,并撰写了文章进行了深入且详尽的分析。


Spring框架开发者们喜欢到处宣扬他们对MongoDB提供的支持,并以此作为优于其他框架的一个资本。不过,如果在真正的项目中使用Spring Data MongoDB的话,你就会发现框架在某些特性上的严重缺失以及设计上的巨大失误。

  Spring Data MongoDB试图将ORM风格的架构硬塞到非关系型数据库中,这直接造成在实际项目中根本无法使用的严重后果,下面就来谈谈这背后的原因:


  无法检索字段,只能获取整个文档


  这是Spring Data MongoDB设计上最大的瑕疵。它试图用SQL数据库中的行对文档进行建模,并且希望你像ORM一样创建“实体”类。这两者根本就不是一回事。文档可要比SQL数据库中的行复杂多了,也大多了。


  对于SQL数据库中的行来说,它认为你在大多数查询中都会获取到里面的所有数据,否则数据就应该被划分到多张表中。不过文档与之完全不同,文档可以嵌套,很多时候你只想从数据库中获取到文档的一个子集而已。


  但对于Spring Data MongoDB的“实体”模型来说,你不得不在每次查询中都检索出整个文档才行。


  没有DBRef延迟加载


  这个就更加疯狂了。如果通过DBRefs来引用其他文档,那么Spring Data MongoDB就会得到整个文档而不是文档引用。如果通过DBRefs连接了大量文档,那么一个只想获得几个字段的简单查询都会导致获取到整个文档图!


  实际情况是这个Bug报告已经有将近两年时间了,被指定为“低优先级”状态,也没有什么解决方案,这太让人难以置信了,这表明Spring Data MongoDB的愿景与实际的使用之间存在着多么大的差距。


  不支持游标


  想要通过游标遍历集合吗?没门。要么就取出整个集合,要么就转而使用原生的Mongo Java驱动。


  不完备的聚合框架支持


  Spring Data MongoDB是从不久之前才开始支持MongoDB聚合框架的,就像框架的其他部分一样,这种支持也是个半成品。


  框架文档很少并且容易让人产生混乱,在实际项目中所需的大多数聚合查询都没法在Spring Data MongoDB的文档中找到,你只能使用原生的驱动才行。


  不完善的索引支持


  虽然可以通过框架将某个字段标记为“加索引的”,但其他操作却根本就不知道这回事。


  就拿MongoDB中的一个例子来说吧,如果某个字段是唯一且稀疏的,那么你就不能使用“null”值向文档中插入一次以上。这意味着在第2次插入时,该字段就不应该在第1次插入的位置处出现。


  然而,由于Spring强迫你在一个类中定义文档的字段,因此最后需要将null赋给不存在的字段。如果该字段拥有唯一的稀疏索引,那么这会导致运行期错误,因为Spring在根据实体对象创建查询时(以注解的形式直接定义在字段上),它根本就不知道索引的存在。


  Spring还提供了一个ensureIndex()方法用于手工在字段上创建索引,无需使用注解,不过文档中并没有提及何时该使用这种方式、使用的频率是多少,以及调用的性能是怎样的。



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部