mongodb的多租户实现其实跟hibernate的多租户实现原理差不多,都是获得数据库连接之后,再切换数据库。
具体代码如下:
mongodb自定义配置类:
import com.mongodb.MongoClient; import com.mongodb.MongoClientOptions; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.data.mongodb.core.MongoTemplate; import javax.annotation.PreDestroy; import java.net.UnknownHostException; @Configuration @EnableAutoConfiguration public class MongodbConfig { @Value("${spring.data.mongodb.default_db}") String defaultName; private final MongoClientOptions options; private MongoClient mongo; public MongodbConfig(MongoProperties properties, ObjectProvider<MongoClientOptions> options, Environment environment) throws UnknownHostException { this.options = (MongoClientOptions)options.getIfAvailable(); this.mongo = properties.createMongoClient(this.options,environment); } @PreDestroy public void close() { if (this.mongo != null) { this.mongo.close(); } } @Bean public MySimpleMongoDbFactory getMongodb(){ MySimpleMongoDbFactory mySimpleMongoDbFactory = new MySimpleMongoDbFactory(mongo,defaultName); return mySimpleMongoDbFactory; } @Bean public MongoTemplate mongoTemplate() throws Exception { return new MongoTemplate(getMongodb()); } }
继承实现mongodb的SimpleMongoDbFactory类
import com.mongodb.DB; import com.mongodb.MongoClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; public class MySimpleMongoDbFactory extends SimpleMongoDbFactory { private static final Logger logger = LoggerFactory.getLogger(MySimpleMongoDbFactory.class); /** * 默认数据库名称 **/ private String defaultName = ""; /** * MongoDB模板类 **/ private MongoTemplate mongoTemplate; /** * 用户所在线程使用数据库集合 **/ private static final ThreadLocal<String> dbName = new ThreadLocal<String>(); public MySimpleMongoDbFactory(MongoClient mongoClient, String databaseName) { super(mongoClient, databaseName); logger.debug("Instantiating " + MySimpleMongoDbFactory.class.getName() + " with default database name: " + databaseName); this.defaultName = databaseName; } public static void switchDatabase(final String databaseName) { logger.debug("Switching to database: " + databaseName); dbName.set(databaseName); } @Override public DB getDb() { final String databaseName = dbName.get(); final String dbToUse = (databaseName != null ? databaseName : this.defaultName); logger.debug("Acquiring database: " + dbToUse); return super.getDb(dbToUse); } }
使用示例:
import com.alibaba.fastjson.JSON; import com.medicalrobot.config.MySimpleMongoDbFactory; import com.medicalrobot.dao.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.Test; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @DirtiesContext public class InterfaceTest extends AbstractTestNGSpringContextTests { @Autowired UserRepository userRepository; @Test public void test(){ MySimpleMongoDbFactory.switchDatabase("test"); /* User user = new User(); user.setId("333"); user.setName("zhangsan"); user.setSex("男"); userRepository.save(user);*/ System.out.println(JSON.toJSONString(userRepository.findAll())); System.out.println("=============================="); MySimpleMongoDbFactory.switchDatabase("test2"); System.out.println(JSON.toJSONString(userRepository.findAll())); } }
user类:
import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document @Data public class User { @Id private String id; private String name; private String sex; }