SpriingBoot整合MongoDB多数据源
背景:
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";@Overridepublic 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));}*/}@Beanpublic 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 {@AutowiredMongoDatabaseFactory 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") //第一个数据源名字oneMongopublic MongoTemplate primaryMongoTemplate() {try {log.info("primaryMongoProperties:" + primaryMongoProperties.getUri());return new MongoTemplate(mongoDatabaseFactory(primaryMongoProperties));} catch (Exception e) {e.printStackTrace();}return null;}@Bean@Primarypublic 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@Primarypublic 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;@Autowiredpublic 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;@Overridepublic 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);}
相关文章:

SpriingBoot整合MongoDB多数据源
背景: MongoDB多数据源:springboot为3以上版本,spring-boot-starter-data-mongodb低版本MongoDBFactory已过时, 改为MongoDatabaseFactory。 1、pom引入: <dependency><groupId>org.springframework.boo…...

深入浅出 -- 系统架构之负载均衡Nginx缓存机制
一、Nginx缓存机制 对于性能优化而言,缓存是一种能够大幅度提升性能的方案,因此几乎可以在各处都能看见缓存,如客户端缓存、代理缓存、服务器缓存等等,Nginx的缓存则属于代理缓存的一种。对于整个系统而言,加入缓存带来…...
前端 小程序框架UniApp
小程序框架UniApp uni-app简介uni-app项目结构uni-app开发工具HBuilderXuni-app页面uni-app页面生命周期uni-app组件生命周期uni-app页面调用接口uni-app页面通讯uni-app pages.json 页面路由uni-app组件viewuni-app组件scroll-viewuni-app组件swiperuni-app组件textuni-app组…...

宏集PLC如何为楼宇自动化行业提供空调、供暖与通风的解决方案?
一、应用背景 楼宇自动化行业是通过将先进的技术和系统应用于建筑物中,以提高其运营效率、舒适度和能源利用效率的行业,其目标是使建筑物能够自动监控、调节和控制各种设备和系统,包括照明系统、空调系统、安全系统、通风系统、电力供应系统…...

【TI毫米波雷达】官方工业雷达包的生命体征检测环境配置及避坑(Vital_Signs、IWR6843AOPEVM)
【TI毫米波雷达】官方工业雷达包的生命体征检测环境配置及避坑(Vital_Signs、IWR6843AOPEVM) 文章目录 生命体征基本介绍IWR6843AOPEVM的配置上位机配置文件避坑上位机start测试距离检测心跳检测呼吸频率检测空环境测试 附录:结构框架雷达基…...

计算机毕业设计选题之基于SSM的旅游管理系统【源码+PPT+文档+包运行成功+部署讲解】
💓项目咨询获取源码联系v💓xiaowan1860💓 🚩如何选题?🍑 对于项目设计中如何选题、让题目的难度在可控范围,以及如何在选题过程以及整个毕设过程中如何与老师沟通,有疑问不清晰的可…...

JavaWeb入门——Web前端概述及HTML,CSS语言基本使用
前言: java基础已经学完,开始学习javaWeb相关的内容,整理下笔记,打好基础,daydayup!!! Web Web:全球广域网,也称万维网(www World Wide Web),能够通过浏览器访…...

数据结构(3)----栈和队列
目录 一.栈 1.栈的基本概念 2.栈的基本操作 3.顺序栈的实现 •顺序栈的定义 •顺序栈的初始化 •进栈操作 •出栈操作 •读栈顶元素操作 •若使用另一种方式: 4.链栈的实现 •链栈的进栈操作 •链栈的出栈操作 •读栈顶元素 二.队列 1.队列的基本概念 2.队列的基…...

nestjs 全栈进阶--module
视频教程 10_模块Module1_哔哩哔哩_bilibili 1. 模块Module 在 Nest.js 中,Module 是框架的核心概念之一,用于组织和管理应用程序的不同部分,包括服务、控制器、中间件以及其他模块的导入。每个 Nest.js 应用程序至少有一个根模块…...

jupyter python paramiko 网络系统运维
概述 通过使用jupyter进行网络运维的相关测试 设备为H3C 联通性测试 import paramiko import time import getpass import re import os import datetimeusername "*****" password "*****" ip "10.32.**.**"ssh_client paramiko.SSHCli…...
Windows Edge浏览器兼容性问题诊断与修复策略详解
随着Microsoft Edge浏览器的持续迭代与更新,其性能与兼容性已得到了显著提升。然而,在面对互联网上纷繁复杂的网页内容时,仍有可能遇到兼容性问题。本文旨在探讨Edge浏览器在处理网页兼容性问题时的常见场景、原因分析及相应的解决方案&#…...
EXCEL学习笔记
EXCEL学习笔记 小技巧 一键批量添加后缀名词/单词 单元格格式-自定义-通用格式后面输入相应的单位,比如“元”。 输入10000个序号,先输入1,点击开始-填充-序列,选中该列,终止值为10000; 按住shift选取多个…...
使用预训练的bert large model实现问答系统源码(本地实现 question answer system)
pre-trained bert model 预训练好的Bert模型 本地实现问答系统 用这条命令将bert下载到本地: model.save_pretrained("path/to/model") 具体代码 如下链接: https://download.csdn.net/download/qqqweiweiqq/89092005...

蓝桥杯 历届真题 杨辉三角形【第十二届】【省赛】【C组】
资源限制 内存限制:256.0MB C/C时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 思路: 由于我第一写没考虑到大数据的原因,直接判断导致只得了40分,下面是我的代码: #…...

商务电子邮件: 在WorkPlace中高效且安全
高效和安全的沟通是任何组织成功的核心。在我们关于电子邮件类型的系列文章的第二期中,我们将重点关注商业电子邮件在促进无缝交互中的关键作用。当你身处重要的工作场环境时,本系列的每篇文章都提供了电子邮件的不同维度的视角。 “2024年,全…...

阿里云2024年优惠券领取及使用常见问题
阿里云是阿里巴巴旗下云计算品牌,服务涵盖云服务器、云数据库、云存储、域名注册等全方位云服务和各行业解决方案。为了吸引用户上云,阿里云经常推出各种优惠活动,其中就包括阿里云优惠券。本文将对阿里云优惠券领取及使用常见问题进行解答&a…...

90天玩转Python—05—基础知识篇:Python基础知识扫盲,使用方法与注意事项
90天玩转Python系列文章目录 90天玩转Python—01—基础知识篇:C站最全Python标准库总结 90天玩转Python--02--基础知识篇:初识Python与PyCharm 90天玩转Python—03—基础知识篇:Python和PyCharm(语言特点、学习方法、工具安装) 90天玩转Python—04—基础知识篇:Pytho…...
常见的常见免费开源绘图工具对比 draw.io/Excalidraw/Lucidchart/yEd Graph Editor/Dia/
拓展阅读 常见免费开源绘图工具 OmniGraffle 创建精确、美观图形的工具 UML-架构图入门介绍 starUML UML 绘制工具 starUML 入门介绍 PlantUML 是绘制 uml 的一个开源项目 UML 等常见图绘制工具 绘图工具 draw.io / diagrams.net 免费在线图表编辑器 绘图工具 excalidr…...

项目:自主实现Boost搜索引擎
文章目录 写在前面开源仓库和项目上线其他文档说明 项目背景项目的宏观原理技术栈与环境搜索引擎原理正排索引倒排索引 去标签和数据清洗模块html文件名路径保存函数html数据解析函数文件写入函数 建立索引模块检索和读取信息建立索引建立正排索引建立倒排索引jieba工具的使用倒…...

麒麟系统ARM安装rabbitmq
简单记录下,信创服务器:麒麟系统,安装rabbitmq的踩坑记录。 本文章参考了很多大佬文章,我整理后提供。 一、安装基础依赖 yum -y install make gcc gcc-c kernel-devel m4 ncurses-devel openssl-devel unixODBC-devel 二、下载…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...