springboot mongodb 动态数据源 分库 分表

springboot+mongodb动态数据源

背景

业务侧分库分表
根据账户切换不同数据库,多个账户在同一个库。例如0001-0005的客户在一个库。
根据账户分表,账户名_表名
其实使用mongodb不用业务侧做这种分库分表,历史原因,还是实现了。

分库

springboot mongodb 的 MongoTemplate 默认是一个database。我们需要动态切换。所以需要改造。

通过跟踪MongoTemplate构造我们发现,有一个关键的类MongoDatabaseFactory database工厂。
在这里插入图片描述

这个接口定义了一个方法getMongoDatabase()。而且他有一个简单的实现SimpleMongoClientDatabaseFactory。其中getMongoDatabase()获取的就是我们配置文件中的数据库名.

// 默认的实现,getDefaultDatabaseName() 就是配置文件中的 database
public MongoDatabase getMongoDatabase() throws DataAccessException {
   
	return getMongoDatabase(getDefaultDatabaseName());
}

按照SimpleMongoClientDatabaseFactory自己实现一个Factory, 其他不变,重写getMongoDatabase()


/**
 * 动态的 DynamicMongoDbFactory
 *
 * @author fengyi
 * @version 1.0
 * @date 2021/3/13 18:41
 */
public class DynamicMongoDbFactory extends MongoDatabaseFactorySupport<MongoClient>
        implements DisposableBean {
   

    private final static Logger LOG = LoggerFactory.getLogger(DynamicMongoDbFactory.class);

    /**
     * Creates a new {@link DynamicMongoDbFactory} instance for the given {@code connectionString}.
     *
     * @param connectionString connection coordinates for a database connection. Must contain a database name and must not
     *                         be {@literal null} or empty.
     * @see <a href="https://docs.mongodb.com/manual/reference/connection-string/">MongoDB Connection String reference</a>
     */
    public DynamicMongoDbFactory(String connectionString) {
   
        this(new ConnectionString(connectionString));
    }

    /**
     * Creates a new {@link DynamicMongoDbFactory} instance from the given {@link MongoClient}.
     *
     * @param connectionString connection coordinates for a database connection. Must contain also a database name and not
     *                         be {@literal null}.
     */
    public DynamicMongoDbFactory(ConnectionString connectionString) {
   
        this(MongoClients.create(connectionString), connectionString.getDatabase(), true);
    }

    /**
     * Creates a new {@link DynamicMongoDbFactory} instance from the given {@link MongoClient}.
     *
     * @param mongoClient  must not be {@literal null}.
     * @param databaseName must not be {@literal null} or empty.
     */
    public DynamicMongoDbFactory(MongoClient mongoClient, String databaseName) {
   
        this(mongoClient, databaseName, false);
    }

    /**
     * Creates a new {@link DynamicMongoDbFactory} instance from the given {@link MongoClient}.
     *
     * @param mongoClient          must not be {@literal null}.
     * @param databaseName         must not be {@literal null} or empty.
     * @param mongoInstanceCreated
     */
    DynamicMongoDbFactory(MongoClient mongoClient, String databaseName, boolean mongoInstanceCreated)<
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要实现在Spring Boot中使用MongoDB动态数据源,可以按照以下步骤进行操作: 1. 导入MongoDBJava驱动和Spring BootMongoDB依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> </dependency> ``` 2. 创建动态数据源配置类,继承AbstractRoutingDataSource类,并实现determineCurrentLookupKey()方法,用于动态获取数据源的key: ```java public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceKey(); } } ``` 3. 创建数据源上下文类DataSourceContextHolder,用于存储当前数据源的key: ```java public class DataSourceContextHolder { private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>(); public static void setDataSourceKey(String dataSourceKey) { CONTEXT_HOLDER.set(dataSourceKey); } public static String getDataSourceKey() { return CONTEXT_HOLDER.get(); } public static void clearDataSourceKey() { CONTEXT_HOLDER.remove(); } } ``` 4. 创建数据源配置类,用于配置多个MongoDB数据源: ```java @Configuration public class DataSourceConfig { @Bean(name = "dataSource1") @ConfigurationProperties(prefix = "spring.data.mongodb.datasource1") public MongoClient mongoClient1() { return MongoClients.create(); } @Bean(name = "dataSource2") @ConfigurationProperties(prefix = "spring.data.mongodb.datasource2") public MongoClient mongoClient2() { return MongoClients.create(); } @Bean public DynamicDataSource dynamicDataSource(@Qualifier("dataSource1") MongoClient dataSource1, @Qualifier("dataSource2") MongoClient dataSource2) { Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("dataSource1", dataSource1); targetDataSources.put("dataSource2", dataSource2); DynamicDataSource dynamicDataSource = new DynamicDataSource(); dynamicDataSource.setTargetDataSources(targetDataSources); dynamicDataSource.setDefaultTargetDataSource(dataSource1); return dynamicDataSource; } } ``` 5. 在需要使用动态数据源的地方,通过调用DataSourceContextHolder.setDataSourceKey()方法来设置当前数据源的key: ```java @Service public class UserServiceImpl implements UserService { @Autowired private MongoTemplate mongoTemplate; @Override public void addUser(User user) { DataSourceContextHolder.setDataSourceKey("dataSource2"); mongoTemplate.save(user); DataSourceContextHolder.clearDataSourceKey(); } } ``` 以上就是在Spring Boot中使用MongoDB动态数据源的步骤,希望能对你有所帮助。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值