MongoDB的API提供了DBObject接口来实现BSONObject的操作方法,BasicDBObject是具体实现。但是并没有提供DBObjectBeanObject的转换。在还没有了解到与spring集成之前,我做了一个简单的转换,要通过映射和动态调用实现两个对象的存取。

代码要处理Bean中的各种类型,并且要控制持久化时的深度:

  • 基础类型(int, float, boolean...)
  • 基础扩展类型(Integer, Float, Boolean)
  • 枚举
  • ObjectId
  • 普通对象 extends Object
  • 业务对象(拥有ObjectId的对象)
  • 容器List, Map, Set(处理元素时要把上面的类型再处理一遍)

虽然代码可以运行并能达到预期,但知道spring-data-mongo这样现成的集成功能包时,还是决定换过来。

spring-data-mongo的实现中有一处和我的实现是相似的,就是在mongodb中元素包含了类型信息来做反序列化,我的实现里用_classname来保存类型信息。

本文只讨论Spring与MongoDB集成的配置,不包括如何使用Mongo、MongoTemplate实例等内容。

spring-data-mongo提供了MongoTemplate来操作bean对象与MongoDB交互,在使用前的关键是如何创建一个MongoTemplate来使用。

1、依赖包

spring与mongo集成需要很多包,可以手工下载或在运行时通过异常信息下载对应的包,很繁琐,建议使用Maven来管理依赖。

要加入的依赖有两个:spring-data-mongo和slf4j的实现,这里选的是slf4j-log4j12。如果不加载slf4j-log4j12,也可以使用其它slf4j的实现,看具体需要。没有加载的话,运行时会提示错误:

  1. SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
  2. SLF4J: Defaulting to no-operation (NOP) logger implementation
  3. SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

把下面的依赖加到pom.xml中的<dependencies />节点中

  1. <dependency>
  2. <groupId>org.springframework.data</groupId>
  3. <artifactId>spring-data-mongodb</artifactId>
  4. <version>1.2.1.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.slf4j</groupId>
  8. <artifactId>slf4j-log4j12</artifactId>
  9. <version>1.7.5</version>
  10. </dependency>

在pom.xml指定使用的spring版本:

  1. <spring.framework.version>3.1.2.RELEASE</spring.framework.version>

增加spring里程碑仓库到pom.xml中

  1. <repositories>
  2. <repository>
  3. <id>spring-milestone</id>
  4. <name>Spring Maven MILESTONE Repository</name>
  5. <url>http://repo.springsource.org/libs-milestone</url>
  6. </repository>
  7. </repositories>

2、集成(连接到MongoDB)

Spring和MongoDB的集成有四种方式,核心就是如何取得MongoTemplate,以及如何设置mongo连接参数,而最终连接到MongoDB上。

1、基本方式

  直接创建MongoTemplate,指定连接时的name,password,database参数等等。这种方式最直接,不需要配置,只要载入相关的jar包。

  MongoTemplate有两个参数,第一个是com.mongodb.Mongo实例,第二个是字符串型的数据库名。

  数据库名不需要解释了,对于第一个参数,可以直接new Mongo(),并给构造函数传入适当的参数:

  1. @Configuration
  2. public class AppConfig {
  3.  
  4. public @Bean
  5. Mongo mongo() throws UnknownHostException {
  6. return new Mongo( "localhost" );
  7. }
  8. }

  或者使用MongoFactoryBean创建Mongo实例

  1. @Configuration
  2. public class AppConfig {
  3.  
  4. public @Bean
  5. MongoFactoryBean mongo() {
  6. MongoFactoryBean mongo = new MongoFactoryBean();
  7. mongo.setHost( "localhost" );
  8. return mongo;
  9. }
  10. }

  无论怎样,都是手工配置。

2、使用XML注册Mongo的实例

  使用(Spring)XML注册Mongo实例的好处是可以方便的配置Mongo参数,还可以简单的配置集群信息。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:mongo="http://www.springframework.org/schema/data/mongo"
  5. xsi:schemaLocation="http://www.springframework.org/schema/context
  6. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  7. http://www.springframework.org/schema/data/mongo
  8. http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
  9. http://www.springframework.org/schema/beans
  10. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  11.  
  12. <!-- Default bean name is 'mongo' -->
  13. <mongo:mongo host="localhost" port="27017" />
  14. </beans>

  如果要配置连接参数可以下面的代码:

  1. <beans>
  2. <mongo:mongo host="localhost" port="27017">
  3. <mongo:options connections-per-host="8"
  4. threads-allowed-to-block-for-connection-multiplier="4"
  5. connect-timeout="1000"
  6. max-wait-time="1500}"
  7. auto-connect-retry="true"
  8. socket-keep-alive="true"
  9. socket-timeout="1500" slave-ok="true"
  10. write-number="1"
  11. write-timeout="0"
  12. write-fsync="true" />
  13. </mongo:mongo/>
  14. </beans>

  配置集群信息:

  1. <mongo:mongo id="replicaSetMongo" replica-set="127.0.0.1:27017,localhost:27018"/>

  上面两种方法是围绕如何直接创建出Mongo实例,而接下来的方法是使用MongoDBFactory来创建DB实例。

3、使用MongoDBFactory

  MongoTemplate的另一组重要构造方法中,有一个是必须的:MongoDBFactory,这是一个接口,定义返回DB实例的方法:

  1. public interface MongoDbFactory {
  2.  
  3. DB getDb() throws DataAccessException;
  4. DB getDb(String dbName) throws DataAccessException;
  5. }

  你可以自己实现这个接口,创建Mongo实例,再返回DB的实例。

  spring提供了一个基本的类:org.springframework.data.mongodb.core.SimpleMongoDbFactory,是MongoDbFactory的简单实现。

  这个类以Mongo实例为参数,可以设置数据库名作为第二个可选参数;如果有更多的配置项,就使用UserCredentials参数作为第三个可选参数。

  使用下面这段代码来创建MongoTemplate。里面的SimpleMongoDBFactory和Mongo实例可以手工创建,也可以通过Ico容器来实现。

  1. public class MongoApp {
  2. private static final Log log = LogFactory.getLog( MongoApp.class );
  3.  
  4. public static void main( String[] args ) throws Exception {
  5. MongoOperations mongoOps = new MongoTemplate( new SimpleMongoDbFactory( new Mongo(), "database" ) );
  6. mongoOps.insert( new Person( "Joe", 34 ) );
  7. log.info( mongoOps.findOne( new Query( where( "name" ).is( "Joe" ) ), Person.class ) );
  8. mongoOps.dropCollection( "person" );
  9. }
  10. }

  如果使用Bean来配置SimpleMongoDbFactory,代码大概是这样:

  1. @Configuration
  2. public class MongoConfiguration {
  3.  
  4. public @Bean
  5. MongoDbFactory mongoDbFactory() throws Exception {
  6. return new SimpleMongoDbFactory( new Mongo(), "database" );
  7. }
  8. }

  如果要配置用户名和密码,要使用UserCredentials类,向SimpleMongoDbFactory的构造方法传递Mongo连接的配置信息:

  1. @Configuration
  2. public class MongoConfiguration {
  3.  
  4. public @Bean
  5. MongoDbFactory mongoDbFactory() throws Exception {
  6. UserCredentials userCredentials = new UserCredentials( "joe", "secret" );
  7. return new SimpleMongoDbFactory( new Mongo(), "database", userCredentials );
  8. }
  9.  
  10. public @Bean
  11. MongoTemplate mongoTemplate() throws Exception {
  12. return new MongoTemplate( mongoDbFactory() );
  13. }
  14. }

4、使用XML配置MongoDbFactory实例

  这种方法把所有的配置项放到独立的配置文件中,使用比较灵活,基本不需要代码来维护与Mongo连接有关的功能。

  用如下代码在<beans />节点下简单配置:

  1. <mongo:db-factory dbname="database">

  或者,配置连接信息:

  1. <mongo:db-factory id="anotherMongoDbFactory"
  2. host="localhost"
  3. port="27017"
  4. dbname="database"
  5. username="joe"
  6. password="secret" />

  一个项目中的spring配置文件内容会比较多,经常修改XML文件并不是一个好办法。spring提供了另一个方法,可以独立加载一个properties文件,在个文件里是MongoDB的配置参数。

  通过<context:property-placeholder />节点配置mongo.properties的位置:

  1. <context:property-placeholder
  2. location="classpath:/com/myapp/mongodb/config/mongo.properties" />
  3.  
  4. <mongo:mongo host="${mongo.host}" port="${mongo.port}">
  5. <mongo:options
  6. connections-per-host="${mongo.connectionsPerHost}"
  7. threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
  8. connect-timeout="${mongo.connectTimeout}"
  9. max-wait-time="${mongo.maxWaitTime}"
  10. auto-connect-retry="${mongo.autoConnectRetry}"
  11. socket-keep-alive="${mongo.socketKeepAlive}"
  12. socket-timeout="${mongo.socketTimeout}"
  13. slave-ok="${mongo.slaveOk}"
  14. write-number="1"
  15. write-timeout="0"
  16. write-fsync="true" />
  17. </mongo:mongo>
  18.  
  19. <mongo:db-factory dbname="database" mongo-ref="mongo" />
  20.  
  21. <bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
  22. <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
  23. </bean>

  <context:property-placeholder />节点的location属性配置成自己项目中的mongo.properties位置。我的配置文件如下:

  1. mongo.host=127.0.0.1
  2. mongo.port=27017
  3. mongo.connectionsPerHost=8
  4. mongo.threadsAllowedToBlockForConnectionMultiplier=4
  5. mongo.connectTimeout=1500
  6. mongo.maxWaitTime=1500
  7. mongo.autoConnectRetry=true
  8. mongo.socketKeepAlive=true
  9. mongo.socketTimeout=1500
  10. mongo.slaveOk=true

  然后,在代码中获取到MongoTemplate的实例:

  1. MongoOperations mongoOps = (MongoTemplate) context.getBean( "anotherMongoTemplate" );

  回头看看上面XML的配置:

  1. 配置mongo.properties的位置
  2. 配置如何创建Mongo实例,使用了(1)的配置
  3. 配置如何创建MongoDbFactory,使用了(2)的配置
  4. 配置MongoTemplate,使用了(3)的配置

  所以,配置spring与mongodb集成的重点是如何创建MongoTemplate实例。

参考:

spring-data-mongo: http://www.springsource.org/spring-data/mongodb

【原】Spring与MongoDB集成:配置的更多相关文章

  1. Spring Boot Redis 集成配置(转)

    Spring Boot Redis 集成配置 .embody{ padding:10px 10px 10px; margin:0 -20px; border-bottom:solid 1px #ede ...

  2. 【原】Spring与MongoDB集成:仓库

    上一篇文章用介绍了如何配置spring-data-mongo连接到MongoDB上,如何创建MongoTemplate.MongoTemplate就相当于一个通用的仓库,可以持久化业务对象. 在spr ...

  3. STS(Spring tool suite)集成配置jdk,maven和Tomcat

    STS是spring官网的一个集成开发工具,最近在学springboot,所以用了. 在本文中将介绍如下内容: 搭建开发的 JDK(1.8) 环境. 配置 Maven 环境. 配置 Tomcat 环境 ...

  4. Spring和Hibernate集成配置

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  5. Spring Data MongoDB 一:入门篇(环境搭建、简单的CRUD操作)

    一.简介 Spring Data  MongoDB 项目提供与MongoDB文档数据库的集成.Spring Data MongoDB POJO的关键功能区域为中心的模型与MongoDB的DBColle ...

  6. 菜鸟调错(四)——Spring与DWR集成,配置文件报错

    背景简介: 该项目是市信用办的一个系统,之前好像是一个石家庄的公司负责的.我属于是半路接手.拿到源码后,根据他们给的简(shao)单(de)明(ke)了(lian)的说明把项目搭起来.结果可想而知,项 ...

  7. Spring+SpringMVC+MyBatis集成(SSM)

    1.导入需要用到的jar包 <dependencies> <!--Spring核心包--> <dependency> <groupId>org.spri ...

  8. Spring Boot WebFlux 集成 Mongodb 数据源操作

    WebFlux 整合 Mongodb 前言 上一讲用 Map 数据结构内存式存储了数据.这样数据就不会持久化,本文我们用 MongoDB 来实现 WebFlux 对数据源的操作. 什么是 MongoD ...

  9. Spring系列之集成MongoDB的2种方法

    MongoDB是最流行的NoSQL数据库,SpringBoot是使用Spring的最佳实践.今天带大家讲一讲SpringBoot集成MongoDB的两种方式,MongoDB的安装自行去官网查询,本地开 ...

随机推荐

  1. 在App里面添加App Store中App链接的解决方法

    详见stackoverflow.com/questions/433907/how-to-link-to-apps-on-the-app-store http://developer.apple.com ...

  2. 【原】Redis-LRU缓存

    Redis高级篇 Redis-LRU缓存 将Redis作为缓存使用时,有时添加新数据时,旧数据是很难被清空的. LRU(Least Recently Used) 近期最少使用算法是常用算法之一. 最大 ...

  3. FreeModbus 移植于STM32 实现Modbus RTU通信

    http://ntn314.blog.163.com/blog/static/161743584201233084434579/ 毕业设计自己要做个基于STM32的PLC能直接跑语句表的,现在看来好像 ...

  4. java 读取文件到String(解决中文乱码)

    在改写V&View(维视)时用到了文件管理,需要从html文档读取字符串,可是一直出现中文乱码,一直解决不了.而且很是意外,我在本地运行代码时就能正常读取中文,当放到tomcat上时全是乱码, ...

  5. DLLImport

    namespace Wintellect.Interop.Sound { using System; using System.Runtime.InteropServices; using Syste ...

  6. Eclipse hangs on loading workbench, eclipse停在启动界面的处理办法

    http://stackoverflow.com/questions/8972034/eclipse-hangs-on-loading-workbench 解答一: In most cases, rm ...

  7. openstack rc

    #!/bin/bash export OS_PROJECT_DOMAIN_ID=default export OS_USER_DOMAIN_ID=default export OS_PROJECT_N ...

  8. 【组队训练】2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest

    好多oj都崩掉了,于是打了cf.. 开始开的最后一题...尼玛题好长终于看完了...神题不会.... I过了好多人..看了下,一眼题...随便敲了下,1A ]; int main(){ int n, ...

  9. 设置IE浏览器代理上网

    在局域网中,服务器可以直接通过IE网上冲浪,而工作站要想通过IE上网,如果是在服务器使用代理软件的情况下,其IE需要设置代理. 步骤一:启动IE浏览器,选择"工具",再" ...

  10. 重看Decorator Pattern,联想到Delegate传递及Flags Enum--欢迎拍砖!

    话说装饰模式(Decorator)的动机是“动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活.[GOF <设计模式>]”.再次学到该模式,有感 ...