SpriingBoot整合MongoDB多数据源

本文介绍了在SpringBoot3及以上版本中,如何替换过时的MongoDBFactory并配置多数据源,包括primary和secondaryMongoDB数据库,同时提到如何消除MongoDB自动添加的_class字段,以及使用MongoPageHelper进行分页查询。
摘要由CSDN通过智能技术生成

背景:

MongoDB多数据源:springboot为3以上版本,spring-boot-starter-data-mongodb低版本MongoDBFactory已过时,
改为MongoDatabaseFactory。

1、pom引入:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
 </dependency>

在这里插入图片描述
2、结构:

在这里插入图片描述
3、连接配置

spring:
  data:
    mongodb:
      primary:
        uri: mongodb://admin:admin!8@192.168.10.112:27017/kuname?authSource=admin&readPreference=primary&appname=MongoDB Compass Community&ssl=false

4、具体内容

package com.hh.framework.config;

import com.hh.framework.page.MongoPageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoConverter;

/**
 * @Description:mongo监听 新增时消除默认添加的 _class 字段保存实体类类型
 **/
@Configuration
public class ApplicationReadyListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    @Qualifier("primaryMongo")
    MongoTemplate primaryMongoTemplate;

    /*@Autowired
    @Qualifier("secondaryMongo")
    MongoTemplate secondaryMongoTemplate;
*/
    private static final String TYPEKEY = "_class";

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        MongoConverter converter = primaryMongoTemplate.getConverter();
        if (converter.getTypeMapper().isTypeKey(TYPEKEY)) {
            ((MappingMongoConverter) converter).setTypeMapper(new DefaultMongoTypeMapper(null));
        }
       /* MongoConverter converter2 = secondaryMongoTemplate.getConverter();
        if (converter2.getTypeMapper().isTypeKey(TYPEKEY)) {
            ((MappingMongoConverter) converter2).setTypeMapper(new DefaultMongoTypeMapper(null));
        }*/
    }

    @Bean
    public MongoPageHelper mongoPageHelper() {
        return new MongoPageHelper(primaryMongoTemplate);
    }

}

package com.hh.framework.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

@Configuration
public class MongoDbConfig {
    @Autowired
    MongoDatabaseFactory mongoDatabaseFactory;
    public @Bean MongoTemplate mongoTemplate() throws Exception {
        //remove _class(insert数据时,mongodb默认生成_class字段)
        MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDatabaseFactory), new MongoMappingContext());
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return new MongoTemplate(mongoDatabaseFactory, converter);
    }

}

package com.hh.framework.config;

import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * @Description:mongo连接配置类
 **/
@Configuration
public class MongoInit {
    @Bean(name = "primaryMongoProperties")
    @Primary
    @ConfigurationProperties(prefix = "spring.data.mongodb.primary")
    public MongoProperties statisMongoProperties() {
        System.out.println("-------------------- primaryMongoProperties init ---------------------");
        return new MongoProperties();
    }

   /* @Bean(name = "secondaryMongoProperties")
    @ConfigurationProperties(prefix = "spring.data.mongodb.secondary")
    public MongoProperties twoMongoProperties() {
        System.out.println("-------------------- secondaryMongoProperties init ---------------------");
        return new MongoProperties();
    }*/

}

package com.hh.framework.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

/**
 * @Description:monngo第一个数据源:primary
 **/
@Slf4j
@Configuration
//jar中含有此类,但此处引入冒红,不影响使用
@EnableMongoRepositories( basePackages = "com.hh.framework.entity.primary",mongoTemplateRef = "primary")
public class PrimaryMongoTemplate {



    @Autowired
    @Qualifier("primaryMongoProperties")
    private MongoProperties primaryMongoProperties;

    @Primary
    @Bean(name = "primaryMongo") //第一个数据源名字oneMongo
    public MongoTemplate primaryMongoTemplate() {

        try {
            log.info("primaryMongoProperties:" + primaryMongoProperties.getUri());
            return new MongoTemplate(mongoDatabaseFactory(primaryMongoProperties));

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Bean
    @Primary
    public MongoDatabaseFactory mongoDatabaseFactory(MongoProperties mongoProperties) {
        return new SimpleMongoClientDatabaseFactory(mongoProperties.getUri());
    }

}

package com.hh.framework.config;

/*import com.mongodb.MongoClientURI;*/
/*import org.springframework.data.mongodb.core.SimpleMongoDbFactory;*/
/*
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
*/

/**
 * @Description: mongo第二个数据源:secondary
 **/
/*
@Configuration
@EnableMongoRepositories(
        basePackages = "com.hh.framework.entity.secondary",
        mongoTemplateRef = "secondary")
 */
public class SecondaryMongoTemplate {

/*
    @Autowired
    @Qualifier("secondaryMongoProperties")
    private MongoProperties secondaryMongoProperties;

    @Primary
    @Bean(name = "secondaryMongo") //第二个数据源名字
    public MongoTemplate primaryMongoTemplate() {

        try {
            log.info("secondaryMongoProperties:" + secondaryMongoProperties.getUri());
            return new MongoTemplate(mongoDatabaseFactory(secondaryMongoProperties));

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Bean
    @Primary
    public MongoDatabaseFactory mongoDatabaseFactory(MongoProperties mongoProperties) {
        return new SimpleMongoClientDatabaseFactory(mongoProperties.getUri());
    }*/
}


package com.hh.framework.entity.primary;

import lombok.Data;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;


@Document(collection = "t_city")
@Data
public class CityEntity {

    private String id;

    private String code;

    private String name;
}

5、以下为工具类:

package com.hh.framework.page;


import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * MongoDB分页查询工具类.
 **/
@Component
public class MongoPageHelper {

    public static final int FIRST_PAGE_NUM = 1;
    public static final String ID = "_id";
    private final MongoTemplate mongoTemplate;

    @Autowired
    public MongoPageHelper(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    /**
     * 分页查询,直接返回集合类型的结果.
     *
     * @see MongoPageHelper#pageQuery(Query,
     * Class, Function, Integer, Integer,
     * String)
     */
    public <T> MongoPageResult<T> pageQuery(Query query, Class<T> entityClass, Integer pageSize,
                                       Integer pageNum) {
        return pageQuery(query, entityClass, Function.identity(), pageSize, pageNum, null);
    }

    /**
     * 分页查询,不考虑条件分页,直接使用skip-limit来分页.
     *
     * @see MongoPageHelper#pageQuery(Query,
     * Class, Function, Integer, Integer,
     * String)
     */
    public <T, R> MongoPageResult<R> pageQuery(Query query, Class<T> entityClass, Function<T, R> mapper,
                                          Integer pageSize, Integer pageNum) {
        return pageQuery(query, entityClass, mapper, pageSize, pageNum, null);
    }

    /**
     * 分页查询.
     *
     * @param query Mongo Query对象,构造你自己的查询条件.
     * @param entityClass Mongo collection定义的entity class,用来确定查询哪个集合.
     * @param mapper 映射器,你从db查出来的list的元素类型是entityClass, 如果你想要转换成另一个对象,比如去掉敏感字段等,可以使用mapper来决定如何转换.
     * @param pageSize 分页的大小.
     * @param pageNum 当前页.
     * @param lastId 条件分页参数, 区别于skip-limit,采用find(_id>lastId).limit分页.
     * 如果不跳页,像朋友圈,微博这样下拉刷新的分页需求,需要传递上一页的最后一条记录的ObjectId。 如果是null,则返回pageNum那一页.
     * @param <T> collection定义的class类型.
     * @param <R> 最终返回时,展现给页面时的一条记录的类型。
     * @return PageResult,一个封装page信息的对象.
     */
    public <T, R> MongoPageResult<R> pageQuery(Query query, Class<T> entityClass, Function<T, R> mapper,
                                          Integer pageSize, Integer pageNum, String lastId) {
        //分页逻辑
        long total = mongoTemplate.count(query, entityClass);
        final Integer pages = (int) Math.ceil(total / (double) pageSize);
        if (pageNum <= 0 || pageNum > pages) {
            pageNum = FIRST_PAGE_NUM;
        }
        final Criteria criteria = new Criteria();
        if (StringUtils.isNotBlank(lastId)) {
            if (pageNum != FIRST_PAGE_NUM) {
                criteria.and(ID).gt(new ObjectId(lastId));
            }
            query.limit(pageSize);
        } else {
            int skip = pageSize * (pageNum - 1);
            query.skip(skip).limit(pageSize);
        }

        final List<T> entityList = mongoTemplate
                .find(query.addCriteria(criteria)
                                .with(Sort.by(Lists.newArrayList(new Order(Direction.ASC, ID)))),
                        entityClass);

        final MongoPageResult<R> pageResult = new MongoPageResult<>();
        pageResult.setTotal(total);
        pageResult.setPages(pages);
        pageResult.setPageSize(pageSize);
        pageResult.setPageNum(pageNum);
        pageResult.setList(entityList.stream().map(mapper).collect(Collectors.toList()));
        return pageResult;
    }

}


package com.hh.framework.page;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 分页结果.
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(Include.NON_NULL)
public class MongoPageResult<T> {

    @Schema(description = "页码,从1开始")
    private Integer pageNum;

    @Schema(description = "页面大小")
    private Integer pageSize;

    @Schema(description = "总数")
    private Long total;

    @Schema(description = "总页数")
    private Integer pages;

    @Schema(description = "数据")
    private List<T> list;

}


package com.hh.framework.page;


import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 分页结果.
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(Include.NON_NULL)
public class MongoPageResult<T> {

    @Schema(description = "页码,从1开始")
    private Integer pageNum;

    @Schema(description = "页面大小")
    private Integer pageSize;

    @Schema(description = "总数")
    private Long total;

    @Schema(description = "总页数")
    private Integer pages;

    @Schema(description = "数据")
    private List<T> list;

}

6、业务模块使用:service层


    @Autowired
    @Qualifier("primaryMongo")
    private MongoTemplate primaryMongoTemplate;


    @Override
    public List getList() {

        Criteria criteria = Criteria.where("id").in().and("code").gte("").lte("");
        Query query = Query.query(criteria).with(Sort.by(Sort.Direction.DESC,"code"));
        return primaryMongoTemplate.find(query, CityEntity.class);
    }

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要简单实现MongoDB数据,可以使用Spring Boot的MongoDB数据配置来实现。首先,在项目的配置文件中添加多个MongoDB数据的配置,如下所示: ``` spring.data.mongodb.uri=第一个MongoDB数据连接地址 spring.data.mongodb.other.uri=第二个MongoDB数据连接地址 ``` 接下来,在代码中使用不同的MongoTemplate来操作不同的MongoDB库。可以通过在代码中注入不同的MongoTemplate对象来实现,如下所示: ```java @Autowired @Qualifier("mongoTemplate") private MongoTemplate mongoTemplate; @Autowired @Qualifier("otherMongoTemplate") private MongoTemplate otherMongoTemplate; ``` 以上代码中,`mongoTemplate`和`otherMongoTemplate`分别对应配置文件中的`mongoTemplate`和`otherMongoTemplate`,可以分别使用它们来操作不同的MongoDB库。 通过以上配置和代码实现,就可以简单实现MongoDB数据。使用不同的MongoTemplate来操作不同的MongoDB库,实现数据的分离和管理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [SpringBoot mongodb数据配置](https://blog.csdn.net/lgk601abc/article/details/129442741)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值