当存储基于文档的 JSON 数据的时候,MongoDB 是我最喜欢的数据库。基于 JVM 的语言在与 MongoDB 交互上有很多种选择。我觉得拿四个最流行的解决方案并且都实现一个用例,对我来说不失为一个好的练习。用例:创建一个可以获取一个城市和距其最近的城市的列表的 REST 服务。
我要比较的四个选择是:标准的MongoDB Java Driver、Jongo、Monphia和Spring Data Mongo。为了简洁,我是用 groovy 完成代码,并且使用 Spring Boot 以减少样板代码。
基础配置
Spring Boot 应用的代码非常简洁,如下:
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
@EnableAutoConfiguration
@ComponentScan
@Configuration
class MongoComparison
{
static void main(String[] args) {
SpringApplication.run(MongoComparison, args);
}
}
同时,我也提供了此次对比所使用的Gradle构建文件:
buildscript {
repositories {
jcenter()
maven {
url 'http://repo.spring.io/milestone'
}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.9.RELEASE")
}
}
apply plugin: 'groovy'
apply plugin: 'spring-boot'
repositories {
jcenter()
maven { url 'http://repo.spring.io/milestone' }
maven { url 'http://www.allanbank.com/repo/' }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-data-mongodb")
compile("org.jongo:jongo:1.1")
compile("org.mongodb.morphia:morphia:0.108")
compile("de.grundid.opendatalab:geojson-jackson:1.2")
compile("org.codehaus.groovy:groovy-all:2.3.6")
}
task wrapper(type: Wrapper) {
gradleVersion = '2.1'
}
因为我使用了 Spring Boot 和 Spring Data MongoDB 框架,一些配置可以忽略。例如,Spring Boot 框架在为 Spring Boot 的应用程序上下文提供了 MongoClient bean 和 MongoTemplate bean。你无需在你的配置文件中额外配置(我是用的是 YAML 风格的配置)。
spring:
groovy:
template:
check-template-location: false
data:
mongodb:
host: "localhost"
database: "citydbdata"
基本框架完成之后,我们可以开始对比。
MongoDB Java驱动
因为所有的连接 MongoDB 的程序,都用到了 MongoDB 原生的 Java 驱动,所以我觉得从 MongoDB Java Driver (下称 Java Driver)开始最合适。Java Driver 是 JVM 上使用 MongoDB 的最底层的途径。也就是说,写出的程序会略显冗长,并且API不如其他的更加用户友好。然而,你使用Java Driver能够实现所有的功能。Java Driver 在 Spring Data MongoDB 里已经自动引入,如果你需要单独使用的话,需要引入相应的依赖。
这是使用Java Driver实现的代码:
import com.mongodb.*
import org.bson.types.ObjectId
import org.geojson.Point
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.*
import org.springframework.web.bind.annotation.*
import javax.annotation.PostConstruct
import static org.springframework.web.bind.annotation.RequestMethod.GET
@RestController
@RequestMapping("/mongoclient")
class CityControllerMongoClient {
final DB db
def dbObjectToCityTransformer = { DBObject it ->
def objectMap = it.toMap()
return new City(_id: objectMap._id, name: objectMap.name, location: new Point(objectMap.location.coordinates[0], objectMap.location.coordinates[1]))
}
@Autowired
CityControllerMongoClient(MongoClient mongoClient) {
db = mongoClient.getDB("citydbmongoclient")
}
@RequestMapping(value="/", method = GET)