设为首页 加入收藏

TOP

简阅MongoDB JVM开发库(一)
2015-11-10 12:27:15 来源: 作者: 【 】 浏览:18
Tags:简阅 MongoDB JVM 开发

当存储基于文档的 JSON 数据的时候,MongoDB 是我最喜欢的数据库。基于 JVM 的语言在与 MongoDB 交互上有很多种选择。我觉得拿四个最流行的解决方案并且都实现一个用例,对我来说不失为一个好的练习。用例:创建一个可以获取一个城市和距其最近的城市的列表的 REST 服务。


我要比较的四个选择是:标准的MongoDB Java Driver、Jongo、Monphia和Spring Data Mongo。为了简洁,我是用 groovy 完成代码,并且使用 Spring Boot 以减少样板代码。


Spring Boot 应用的代码非常简洁,如下:


同时,我也提供了此次对比所使用的Gradle构建文件:


因为我使用了 Spring Boot 和 Spring Data MongoDB 框架,一些配置可以忽略。例如,Spring Boot 框架在为 Spring Boot 的应用程序上下文提供了 MongoClient bean 和 MongoTemplate bean。你无需在你的配置文件中额外配置(我是用的是 YAML 风格的配置)。


基本框架完成之后,我们可以开始对比。


因为所有的连接 MongoDB 的程序,都用到了 MongoDB 原生的 Java 驱动,所以我觉得从 MongoDB Java Driver (下称 Java Driver)开始最合适。Java Driver 是 JVM 上使用 MongoDB 的最底层的途径。也就是说,写出的程序会略显冗长,并且API不如其他的更加用户友好。然而,你使用Java Driver能够实现所有的功能。Java Driver 在 Spring Data MongoDB 里已经自动引入,如果你需要单独使用的话,需要引入相应的依赖。


这是使用Java Driver实现的代码:


Java Driver 整体以 DBObject 为中心,你需要一直提供领域对象和DBObject之间的映射。Java Driver没有提供任何形式的对象映射。幸运的是, DBObject 的结构很像 map,并且 Groovy Map 的简洁的风格让其操作起来方便许多。本例中,要找到距某城市最近的城市以及其最短距离时,需要用到 geoNear 命令,你可能需要从 mongoDB 的手册找到其详细的语法。语法缩略如下:


geoNear 命令会返回集合中距离最近的对象,并且提供一个字段来标识他们之间的距离;距离的单位是米。 geoNear 命令中的near字段的格式有两种,一种是上面代码示例,另一种是更传统的2个 double 值组成的数组。因为前一种符合 GeoJSON 的标准,我更推荐这种方式。在我所有的例子中,我尽量都是用 GeoJSON 记法来存储地理位置信息数据。从代码里能看出来,我使用了一个提供了所有 GeoJSON 类型支持的 Java 类库。


撇开所有 DBObject 到领域对象的约定,例子中的代码都非常易读。当然你需要知道 MongoDB 查询的细节;然而当你了解了之后,Java Driver 就是一个非常强大的工具。


Jongo 框架支持基于字符串的交互和查询(查询时不需要创建 DBObject ),因此允许你使用接近于 Mongo Shell 的方式与 MongoDB 实例进行交互。Jongo 使用 Jackson 框架来完成对象映射,所以无需将查询结果和想插入的数据转换为 DBObject 实例。我在使用的 GeoJSON 库内置了Jackson 的支持,对此,我们无需为此多编写代码。


Jongo的用例的代码如下:


从例子中可以看出,Jongo 更面向字符串,尤其是使用 GeoNear 命令查询的时候。同时,多亏 Jackson 框架,我们查询和插入时,不用编写任何的转换的代码。


如果你是先接触到MongoDB,熟悉shell命令并且不想做手工映射的话,Jongo是非常便捷的。但是,你需要去了解Mongo Shell API的确切语法;同时,你在构造查询、编写命令式没有自动的代码补全,如果你觉得这样是可以接受的话,Jongo是一个不错的选择。


MongoDB 的开发者(因为Trisha Gee,我不能说汉子们)为MongoDB量身定做了一个映射框架。 Morphia是一个注解驱动的框架,也就是说为了使用 Morphia ,你得使用注解来注释你的 POJO (尽管如此,你可以不写注解以使用默认的注解)。 Morphia 支持 MongoDB 的大部分函数,遗憾的是没有对 GeoJSON 提供支持从而也不支持 geoNear。MongoDB 的开发者专注的开发 MongoDB Java Driver 3.0,有些忽略 Morphia。 可能会在未来的版本中提供对 GeoJSON 的支持。


因为我用到了 geoNear 函数,除了把Java Driver的测试用例中的代码中的拿来复用也没有更好的选项了。如下是用 Morphia 实现的用例:


因为 Morphia 框架没有对 GeoJSON 提供支持,所以,你要么使用传统的用包含两个坐标的 double 类型的数组,要么写你自己的转换器。我选择了后者,毕竟也不是那么难写。不要忘了把你的转换器加入到 Morphia 中。从代码中可以看出,我已经使用 Morphia 的注解注释了 City 类,对于那些熟悉 JPA 的开发者来说,这种方式直截了当。同时,因为 Morphia 不提供 2dsphere index 查询支持,你要自己创建 2dsphere ?索引。


最后但同样重要的是 Spring Data,我在研究如何用它完成这个用例。如果你熟知 Spring Data 框架的话,你需要写与数据存储交互的库接口,使用方法名来指定你需要使用的查询。在此例中,我们只需要两个查询:根据名字查询城市,找到距某城市最近的城市。Spring Data 框架支持 geospatial 查询(地理空间查询)。


Spring Data 框架有用来表示地理空间坐标的类,但是和 GeoJSON 不兼容(再提一遍:Spring 有其自有的方式)。所幸 Spring Data 能够自动生成索引并且 mongo 也能够处理 Spring Data 使用的坐标表示方式。


这是针对Morphia的实现:译注:我认为是原文错误


就可读性来说,Spring Data 无疑是最好的。你不需要知道 MongoDB 里的查询语句是如何构建的,你只需要使用库中的命名惯例就好。当你使用2dsphere 索引的时候,要记住一点,就是使用 near query 方法时要加入 distance 参数,不然 Spring Data 在查询 MongoDB 时会忽略 sphere 选项(在此情况下会失败?报错)。如果你不需要距离,你可以把命令的返回值城市对象的列表。你不用实现相应的接口,Spring Data 框架会替你实现。


使用Spring Data MongoDB 框架的时候,你也可以使用 MongoTemplate 类。MongoTemplate 类提供了一种类似于 Jongo 和 Java Driver 的机制。使用 MongoTemplate 可以很容易的实现geoNear 查询。


你也可能已经注意到,Spring Data MongoDB 是唯一一个没有在Java代码中提供数据库名字的框架。这是因为Spring Data使用MongoTemplate,而 MongoTemplate 需要你在配置文件中配置。也就是说,你可以将数据库的名字注入到对应的变量上,并且使用此变量来代表数据库的名字。


对于Spring Data Mongo唯一不满意的地方就是他们选取了一种不标准的方式来表示地理信息数据。如果你有一个mongo的集合,集合里全是使用Ge

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Oracle行转列与列转行 下一篇MySQL 数据高可用的实现思路

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: