spring-data-mongodb在一个Mongo实例中连接多个数据库

新手上路,请多包涵

我正在使用最新的 spring-data-mongodb (1.1.0.M2) 和最新的 Mongo 驱动程序 (2.9.0-RC1)。我有一种情况,我有多个客户端连接到我的应用程序,我想在同一个 Mongo 服务器中为每个客户端提供自己的“模式/数据库”。如果我直接使用驱动程序,这不是一个很难实现的任务:

 Mongo mongo = new Mongo( new DBAddress( "localhost", 127017 ) );

DB client1DB = mongo.getDB( "client1" );
DBCollection client1TTestCollection = client1DB.getCollection( "test" );
long client1TestCollectionCount = client1TTestCollection.count();

DB client2DB = mongo.getDB( "client2" );
DBCollection client2TTestCollection = client2DB.getCollection( "test" );
long client2TestCollectionCount = client2TTestCollection.count();

看,容易。但是 spring-data-mongodb 不允许使用多个数据库的简单方法。建立与 Mongo 的连接的首选方法是扩展 AbstractMongoConfiguration 类:

您将看到您重写了以下方法:

 getDatabaseName()

因此,它会强制您使用一个数据库名称。然后,您构建的存储库接口使用传递到 SimpleMongoRepository 类的 MongoTemplate 中的数据库名称。

我究竟应该在哪里粘贴多个数据库名称?我必须创建多个数据库名称,多个 MongoTempate s(每个数据库名称一个),以及多个其他配置类。这仍然无法让我的存储库接口使用正确的模板。如果有人尝试过这样的事情,请告诉我。如果我弄明白了,我会在这里发布答案。

谢谢。

原文由 sbzoom 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 733
2 个回答

因此,经过大量研究和实验,我得出结论,当前的 spring-data-mongodb 项目还不可能做到这一点。我尝试了上面 baja 的方法并遇到了一个特定的障碍。 MongoTemplate 从其构造函数中运行其 ensureIndexes() 方法。此方法调用数据库以确保数据库中存在带注释的索引。 MongoTemplate 的构造函数在 Spring 启动时被调用,所以我什至没有机会设置 ThreadLocal 变量。我必须在 Spring 启动时设置默认值,然后在收到请求时更改它。这是不允许的,因为我不想也没有默认数据库。

一切都没有丢失。我们最初的计划是让每个客户端在自己的应用程序服务器上运行,指向自己的 MongoDB MongoDB 服务器上的数据库。然后我们可以提供一个 -Dprovider= 系统变量,每台服务器只指向一个数据库运行。

我们被指示拥有一个多租户应用程序,因此尝试使用 ThreadLocal 变量。但由于它不起作用,我们能够按照我们最初设计的方式运行该应用程序。

我相信有一种方法可以使这一切正常进行,只是需要比其他帖子中描述的更多。你必须自己制作 RepositoryFactoryBean 。这是 Spring Data MongoDB 参考文档 中的示例。您仍然需要实施自己的 MongoTemplate 并延迟或删除 ensureIndexes() 调用。但是您必须重写一些类以确保调用您的 MongoTemplate 而不是 Spring's 。换句话说,很多工作。我希望看到发生甚至去做的工作,我只是没有时间。

感谢您的回复。

原文由 sbzoom 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是我认为您正在寻找的文章的链接 http://michaelbarnesjr.wordpress.com/2012/01/19/spring-data-mongo/

关键是提供多个模板

为每个数据库配置一个模板。

 <bean id="vehicleTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg ref="mongoConnection"/>
    <constructor-arg name="databaseName" value="vehicledatabase"/>
</bean>

为每个数据库配置一个模板。

 <bean id="imageTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg ref="mongoConnection"/>
        <constructor-arg name="databaseName" value="imagedatabase"/>
</bean>

<bean id="vehicleTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg ref="mongoConnection"/>
    <constructor-arg name="databaseName" value="vehicledatabase"/>
</bean>

现在,您需要告诉 Spring 您的存储库在哪里,以便它可以注入它们。它们必须都在同一个目录中。我试图将它们放在不同的子目录中,但它无法正常工作。所以它们都在存储库目录中。

 <mongo:repositories base-package="my.package.repository">
    <mongo:repository id="imageRepository" mongo-template-ref="imageTemplate"/>
    <mongo:repository id="carRepository" mongo-template-ref="vehicleTemplate"/>
    <mongo:repository id="truckRepository" mongo-template-ref="vehicleTemplate"/>
</mongo:repositories>

每个repository都是一个Interface,写法如下(是的,你可以留空):

 @Repository
public interface ImageRepository extends MongoRepository<Image, String> {

}

@Repository
public interface TruckRepository extends MongoRepository<Truck, String> {

}

私有变量的名字 imageRepository 就是集合! Image.java 将保存到 imagedb 数据库中的图像集合中。

以下是 _查找_、 插入删除 记录的方法:

 @Service
public class ImageService {

    @Autowired
    private ImageRepository imageRepository;
}

通过自动装配,您可以将变量名称与配置中的名称 (id) 匹配。

原文由 john 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题