• 【原】Spring与MongoDB集成:配置


    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的实现,看具体需要。没有加载的话,运行时会提示错误:

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

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

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>1.2.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.5</version>
    </dependency>

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

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

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

    <repositories>
        <repository>
            <id>spring-milestone</id>
            <name>Spring Maven MILESTONE Repository</name>
            <url>http://repo.springsource.org/libs-milestone</url>
        </repository>
    </repositories>

    2、集成(连接到MongoDB)

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

    1、基本方式

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

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

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

    @Configuration
    public class AppConfig {
    
        public @Bean
        Mongo mongo() throws UnknownHostException {
            return new Mongo( "localhost" );
        }
    }

        或者使用MongoFactoryBean创建Mongo实例

    @Configuration
    public class AppConfig {
    
        public @Bean
        MongoFactoryBean mongo() {
            MongoFactoryBean mongo = new MongoFactoryBean();
            mongo.setHost( "localhost" );
            return mongo;
        }
    }

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

    2、使用XML注册Mongo的实例

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

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mongo="http://www.springframework.org/schema/data/mongo"
        xsi:schemaLocation="http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
            http://www.springframework.org/schema/data/mongo
            http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
        <!-- Default bean name is 'mongo' -->
        <mongo:mongo host="localhost" port="27017" />
    </beans>

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

    <beans>
        <mongo:mongo host="localhost" port="27017">
            <mongo:options connections-per-host="8"
                threads-allowed-to-block-for-connection-multiplier="4"
                connect-timeout="1000" 
                max-wait-time="1500}" 
                auto-connect-retry="true"
                socket-keep-alive="true" 
                socket-timeout="1500" slave-ok="true"
                write-number="1" 
                write-timeout="0" 
                write-fsync="true" />
        </mongo:mongo/>
    </beans>

       配置集群信息:

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

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

    3、使用MongoDBFactory

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

    public interface MongoDbFactory {
        
        DB getDb() throws DataAccessException;
        DB getDb(String dbName) throws DataAccessException;
    }

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

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

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

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

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

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

    @Configuration
    public class MongoConfiguration {
    
        public @Bean
        MongoDbFactory mongoDbFactory() throws Exception {
            return new SimpleMongoDbFactory( new Mongo(), "database" );
        }
    }

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

    @Configuration
    public class MongoConfiguration {
    
        public @Bean
        MongoDbFactory mongoDbFactory() throws Exception {
            UserCredentials userCredentials = new UserCredentials( "joe", "secret" );
            return new SimpleMongoDbFactory( new Mongo(), "database", userCredentials );
        }
    
        public @Bean
        MongoTemplate mongoTemplate() throws Exception {
            return new MongoTemplate( mongoDbFactory() );
        }
    }

    4、使用XML配置MongoDbFactory实例

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

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

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

      或者,配置连接信息:

    <mongo:db-factory id="anotherMongoDbFactory" 
        host="localhost"
        port="27017" 
        dbname="database" 
        username="joe" 
        password="secret" />

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

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

    <context:property-placeholder
        location="classpath:/com/myapp/mongodb/config/mongo.properties" />
    
    <mongo:mongo host="${mongo.host}" port="${mongo.port}">
        <mongo:options 
            connections-per-host="${mongo.connectionsPerHost}"
            threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
            connect-timeout="${mongo.connectTimeout}" 
            max-wait-time="${mongo.maxWaitTime}"
            auto-connect-retry="${mongo.autoConnectRetry}" 
            socket-keep-alive="${mongo.socketKeepAlive}"
            socket-timeout="${mongo.socketTimeout}" 
            slave-ok="${mongo.slaveOk}"
            write-number="1" 
            write-timeout="0" 
            write-fsync="true" />
    </mongo:mongo>
    
    <mongo:db-factory dbname="database" mongo-ref="mongo" />
    
    <bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    </bean>

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

    mongo.host=127.0.0.1
    mongo.port=27017
    mongo.connectionsPerHost=8
    mongo.threadsAllowedToBlockForConnectionMultiplier=4
    mongo.connectTimeout=1500
    mongo.maxWaitTime=1500
    mongo.autoConnectRetry=true
    mongo.socketKeepAlive=true
    mongo.socketTimeout=1500
    mongo.slaveOk=true

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

    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

  • 相关阅读:
    (一) kinect概述
    (五)摇杆/按钮/触摸板
    (四)Trigger
    (三)快速添加touch事件
    (二)简单触控
    Java程序设计当堂测试 9.20
    Java程序设计当堂测试感受
    暑假生活第八周总结
    暑假生活第七周总结
    暑假生活第六周总结
  • 原文地址:https://www.cnblogs.com/basecn/p/springmongo_intergration_cfg.html
Copyright © 2020-2023  润新知