博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring data mongodb配置+月库实现
阅读量:6271 次
发布时间:2019-06-22

本文共 3700 字,大约阅读时间需要 12 分钟。

基础的东西不谈,先说思路。

我们跟踪源码可以发现每次查询时都会在MongoTemplate中去获取MongoDatabase实例,大概是这样:

FindIterable
iterable = collectionCallback .doInCollection(getAndPrepareCollection(getDb(), collectionName));复制代码

其中getDb()是由工厂类MongoDbFactory实现的。那么很简单了,我们只需要写一个自己的MongoDbFactory配置进来,来实现“默认是当前月库,也可以手动选择月库”的效果。

上代码,首先是MongoDbFactory

/** * 继承 {
@link SimpleMongoDbFactory },重写{
@code getDB}方法,添加月库实现 * * @author fonlin * @date 2018/6/28 */public class MonthlyMongoDbFactory extends SimpleMongoDbFactory { /** * 没有月库后缀的数据库名 */ private String databaseName; public MonthlyMongoDbFactory(MongoClientURI uri) { super(uri); } public MonthlyMongoDbFactory(MongoClient mongoClient, String databaseName) { super(mongoClient, databaseName); this.databaseName = databaseName; } public MongoDatabase getDb() throws DataAccessException { //获取当前ThreadLocal中的month String month = MonthSelector.getAndRemove(); //如果没有,则设置当前月 if (StringUtils.isEmpty(month)) { month = LocalDateTime.now().format(DateTimeFormatter.ofPattern(Constants.MONTH_PATTERN)); } return getDbByMonth(month); } private MongoDatabase getDbByMonth(String month) throws DataAccessException { Assert.hasText(month, "month must not be empty."); //拼出test_201806 String name = this.databaseName + "_" + month; //调用父类 return super.getDb(name); }}复制代码

很简单,继承默认实现SimpleMongoDbFactory,重写getDb()方法加入我们自己的逻辑,最终还是调用父类的getDb(String dbName)方法。注意MonthSelector,这是利用ThreadLocal实现的手动选择月份策略,用法大概就是这样子:

MonthSelector.set("201805");List
users = userDao.findAll();复制代码

这里把MonthSelector粗略代码贴一下,不太懂的朋友们要去看下ThreadLocal的。

/** * @author fonlin * @date 2018/6/28 */public class MonthSelector {    private static final ThreadLocal
LOCAL_MONTH = new ThreadLocal<>(); public static String getAndRemove() { String month = LOCAL_MONTH.get(); LOCAL_MONTH.remove(); return month; } public static void set(String month) { Assert.notNull(month, "month must not be null"); LOCAL_MONTH.set(month); } public static String get() { return LOCAL_MONTH.get(); }}复制代码

最后是springboot整合mongodb的java config:

@Configuration//必须要禁用spring boot的自动配置@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})@EnableConfigurationProperties(MongoProperties.class)//激活@Repository注解,并且设置dao扫描包@EnableMongoRepositories(basePackages = "com.fonlin.cloudmanager.dao.mongodb")public class MongoDbConfig extends AbstractMongoConfiguration {    private final MongoProperties properties;    private final MongoClientFactory factory;    private final MongoClientOptions options;    private MongoClient mongo;    public MongoDbConfig(MongoProperties properties,                         ObjectProvider
options, Environment environment) { this.properties = properties; this.options = options.getIfAvailable(); this.factory = new MongoClientFactory(properties, environment); } @Bean public MongoDbFactory mongoDbFactory() { //这里new我们自己的MongoDbFactory即可 return new MonthlyMongoDbFactory(mongoClient(), getDatabaseName()); } @PreDestroy public void close() { if (this.mongo != null) { this.mongo.close(); } } @Override public MongoClient mongoClient() { this.mongo = this.factory.createMongoClient(this.options); return this.mongo; } @Override protected String getDatabaseName() { return this.properties.getDatabase(); }}复制代码

到此配置就结束了,使用的话就像jpa Repository一样使用即可。

转载于:https://juejin.im/post/5b35c2836fb9a00e8b253b7e

你可能感兴趣的文章
什么是WeakHashMap--转
查看>>
js 面试题
查看>>
第二十二节,三元运算
查看>>
Yacc 与 Lex 快速入门
查看>>
Unity中HDR外发光的使用
查看>>
Flume负载均衡配置
查看>>
Ajax详解
查看>>
Ubuntu C/C++开发环境的安装和配置
查看>>
百世汇通快递地区选择插件,单独剥离
查看>>
Linux系统调用---同步IO: sync、fsync与fdatasync【转】
查看>>
【MyBatis学习06】输入映射和输出映射
查看>>
[LeetCode] Decode String 解码字符串
查看>>
数字逻辑的一些基本运算和概念
查看>>
ant重新编译打包hadoop-core-1.2.1.jar时遇到的错
查看>>
【★★★★★】提高PHP代码质量的36个技巧
查看>>
3 weekend110的配置hadoop(格式化) + 一些问题解决 + 未免密码配置
查看>>
JavaScript Creating 对象
查看>>
Java compiler level does not match the version of the installed Java project facet.(转)
查看>>
WPF MediaElement.Position属性
查看>>
sqoop数据迁移(基于Hadoop和关系数据库服务器之间传送数据)
查看>>