當MongoDB主鍵為String時,mongoTemplate無法根據id查詢的問題

MongoDB推薦使用ObjectId作為主鍵,但國內的開發都知道,事情往往不如人所愿,當我們真的出現了“_id”主鍵的類型為String時,且還必須想用mongoTemplate.findOne或findList時,直接使用該方法會導致查詢結果為空。

因為mongoTemplate會在查詢的時候將主鍵轉換為ObjectId。

實際上這一步轉換是MappingMongoConverter中做的,源碼如下:

	/*** Converts the given raw id value into either {@link ObjectId} or {@link String}.** @param id can be {@literal null}.* @param targetType must not be {@literal null}.* @return {@literal null} if source {@literal id} is already {@literal null}.* @since 2.2*/
@Nullabledefault Object convertId(@Nullable Object id, Class<?> targetType) {if (id == null || ClassUtils.isAssignableValue(targetType, id)) {return id;}if (ClassUtils.isAssignable(ObjectId.class, targetType)) {if (id instanceof String) {if (ObjectId.isValid(id.toString())) {return new ObjectId(id.toString());}// avoid ConversionException as convertToMongoType will return String anyways.return id;}}try {return getConversionService().canConvert(id.getClass(), targetType)? getConversionService().convert(id, targetType): convertToMongoType(id, (TypeInformation<?>) null);} catch (ConversionException o_O) {return convertToMongoType(id,(TypeInformation<?>)  null);}}

注意示例版本為spring-data-mongodb:3.3.5,一些更古早的版本,如2.1.9,需要重寫其他部分,如果有人需要請留言,我會抽時間補充,但鑒于之前的版本有比較重大的漏洞,所以推薦升級版本。

?if (ObjectId.isValid(id.toString())) { return new ObjectId(id.toString()); }

這段就是mongoTemplate將String轉換為ObjectId的步驟。

所以我們要做的就是重寫這部分,并且替換掉原有的:

1、新建一個Converter

public class MyMongoConverter extends MappingMongoConverter {public MyMongoConverter(DbRefResolver dbRefResolver, MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {super(dbRefResolver, mappingContext);}@Overridepublic Object convertId(@Nullable Object id, Class<?> targetType) {if (id == null || ClassUtils.isAssignableValue(targetType, id)) {return id;}if (ClassUtils.isAssignable(ObjectId.class, targetType)) {if (id instanceof String) {return id;}}try {return getConversionService().canConvert(id.getClass(), targetType)? getConversionService().convert(id, targetType): convertToMongoType(id, (TypeInformation<?>) null);} catch (ConversionException o_O) {return convertToMongoType(id,(TypeInformation<?>)  null);}}
}

2、在構建MongoTemplate時用我們自己寫的替換

MongoTemolate mongoTemplate = new MongoTemplate(mongoDbFactory(), getDefaultMongoConverter(mongoDbFactory()))protected static MongoConverter getDefaultMongoConverter(MongoDatabaseFactory factory) {DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);MongoCustomConversions conversions = new MongoCustomConversions(Collections.emptyList());MongoMappingContext mappingContext = new MongoMappingContext();mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());mappingContext.afterPropertiesSet();MyMongoConverter converter = new MyMongoConverter(dbRefResolver, mappingContext);converter.setCustomConversions(conversions);converter.afterPropertiesSet();converter.setTypeMapper(new DefaultMongoTypeMapper(null));return converter;}/*** @return {@link MongoDatabaseFactory}*/protected MongoDatabaseFactory mongoDbFactory() {ServerAddress serverAddress = new ServerAddress(host, port);MongoClientSettings.Builder setting = MongoClientSettings.builder().applyToClusterSettings(builder -> builder.hosts(Collections.singletonList(serverAddress))).retryWrites(false);if (ObjectUtil.isNotEmpty(username)) {MongoCredential credential = MongoCredential.createCredential(username, authenticationDatabase, password.toCharArray());setting.credential(credential);}MongoClient mongoClient = MongoClients.create(setting.build());return new SimpleMongoClientDatabaseFactory(mongoClient, database);}

host,port,username,authenticationDatabase,password,database

分別為MongoDB的地址,端口號,用戶名,認證數據庫,密碼,數據庫名

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/215394.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/215394.shtml
英文地址,請注明出處:http://en.pswp.cn/news/215394.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

https 協議

目錄 加密方式 對稱加密 非對稱加密 非對稱加密 非對稱加密 非對稱加密 對稱加密 AC證書 AC證書內容 數據摘要 數據簽名 在我們前面學習的http協議里面&#xff0c;我們發送的內容都是明文傳輸的&#xff0c;所以在安全上并不安全&#xff0c;但是在現在信息發達的時…

Java高級技術:優化性能與擴展性的最佳實踐

標題&#xff1a;Java高級技術&#xff1a;優化性能與擴展性的最佳實踐 摘要&#xff1a;本文將介紹Java中一些高級技術&#xff0c;以提高性能和代碼的擴展性。本文不包括反射和并發編程&#xff0c;旨在幫助開發者進一步提升Java應用程序的質量和可維護性。 優化性能的最佳實…

面試題目總結(三)

1. Spring、Springboot、springMVC、Spring Cloud 的區別&#xff1a; Spring&#xff1a;Spring 是一個開源的、輕量級的Java框架&#xff0c;提供了豐富的功能和組件&#xff0c;用于構建企業級應用程序。Spring框架包含了很多模塊&#xff0c;包括核心容器、數據訪問、事物…

MATLAB算法實戰應用案例精講-【數模應用】漫談機器學習(七)

目錄 幾個高頻面試題目 機器學習算法工程師需要掌握哪些編程語言? 1.Python 2. C# 3.JavaScript 4. R 5.Java

Linux之Apache服務器安裝及配置

一、Apache服務器簡介 Apache HTTP Server&#xff08;簡稱Apache&#xff09;是Apache軟件基金會的一個開放源碼的網頁服務器&#xff0c;可以在大多數計算機操作系統中運行&#xff0c;由于其多平臺和安全性被廣泛使用。Apache曾經是世界使用排名第一的Web服務器軟件&#xf…

VSCODE連接遠程服務器

安裝ssh插件 根據你的操作系統選擇對應的版本進行下載和安裝。 安裝完成之后&#xff0c;啟動vscode&#xff0c;選擇左側Extensions 選項卡&#xff0c;在輸入框搜索 remote &#xff0c;選擇安裝Remote-SSH插件。 安裝完成之后會在左側新增一個選項卡Remote Explorer&#xf…

肥貓游戲報價器|計價器|王者榮耀代練陪練等游戲報價器軟件介紹說明

目錄 1. 前言2. 軟件著作權3. 軟件使用說明3.1 進入軟件3.2 用戶登錄3.3 首頁3.4 報價器3.4.1 總體介紹3.4.2 王者報價器3.4.3 LOL手游報價器3.4.4 英雄聯盟報價器3.4.5 云頂之弈報價器3.4.7 王者水晶報價器3.4.8 和平精英報價器3.4.9 蛋仔派對報價器3.4.10 穿越火線報價器3.4.…

kafka學習筆記--broker工作流程、重要參數

本文內容來自尚硅谷B站公開教學視頻&#xff0c;僅做個人總結、學習、復習使用&#xff0c;任何對此文章的引用&#xff0c;應當說明源出處為尚硅谷&#xff0c;不得用于商業用途。 如有侵權、聯系速刪 視頻教程鏈接&#xff1a;【尚硅谷】Kafka3.x教程&#xff08;從入門到調優…

Linux mc命令教程:如何有效地使用mc命令(附案例詳解和注意事項)

Linux mc命令介紹 mc命令是Linux中的一個視覺文件管理器&#xff0c;全稱為Midnight Commander。它提供了一個用戶友好的界面&#xff0c;使得在Linux環境中的文件和目錄管理變得更加直觀和方便。mc命令支持鼠標操作和顏色顯示&#xff0c;同時也提供了一套菜單接口&#xff0…

TypeScript 常用高級類型

目錄 前言&#xff1a; TypeScript 常用高級類型 基本概念 高級類型 1. 交叉類型&#xff08;Intersection Types&#xff09; 2. 聯合類型&#xff08;Union Types&#xff09; 3. 映射類型&#xff08;Mapped Types&#xff09; 4. 條件類型&#xff08;Conditional…

GGML 或GGUF的14種不同量化模式說明

查看 TheBloke/Llama-2–13B-chat-GGML 存儲庫中的文件&#xff0c;我們可以看到 14 種不同的 GGML 模型&#xff0c;對應于不同類型的量化。它們遵循特定的命名約定&#xff1a;“q” 用于存儲權重的位數&#xff08;精度&#xff09; 特定變體。以下是所有可能的量化方法及其…

Pytorch-Transformer軸承故障一維信號分類(三)

目錄 前言 1 數據集制作與加載 1.1 導入數據 第一步&#xff0c;導入十分類數據 第二步&#xff0c;讀取MAT文件驅動端數據 第三步&#xff0c;制作數據集 第四步&#xff0c;制作訓練集和標簽 1.2 數據加載&#xff0c;訓練數據、測試數據分組&#xff0c;數據分batch…

據房間Id是否存在,判斷當前房間是否到期且實時更改顏色

重點代碼展示&#xff1a; <template><el-col style"width: 100%;height: 100%;"><el-col :span"20"><el-card class"room_info"><avue-data-icons :option"option"></avue-data-icons></el-…

RT-DETR算法優化改進:輕量化自研設計雙卷積重新設計backbone和neck,完成漲點且計算量和參數量顯著下降

??????本文自研創新改進:雙卷積由組卷積和異構卷積組成,執行 33 和 11 卷積運算代替其他卷積核僅執行 11 卷積,YOLOv8 Conv,從而輕量化RT-DETR,性能如下表,GFLOPs 8.1降低至7.6,參數量6.3MB降低至5.8MB RT-DETR魔術師專欄介紹: https://blog.csdn.net/m0_637742…

ubuntu-c++-可執行模塊-動態鏈接庫-鏈接庫搜索-基礎知識

文章目錄 1.動態鏈接庫簡介2.動態庫搜索路徑3.運行時鏈接及搜索順序4.查看可運行模塊的鏈接庫5.總結 1.動態鏈接庫簡介 動態庫又叫動態鏈接庫&#xff0c;是程序運行的時候加載的庫&#xff0c;當動態鏈接庫正確安裝后&#xff0c;所有的程序都可以使用動態庫來運行程序。動態…

Android帝國之日志系統--logd、logcat

本文概要 這是Android系統進程系列的第四篇文章&#xff0c;本文以自述的方式來介紹logd進程&#xff0c;通過本文您將了解到logd進程存在的意義&#xff0c;以及日志系統的實現原理。&#xff08;文中的代碼是基于android13&#xff09; Android系統進程系列的前三篇文章如下…

C#基礎與進階擴展合集-基礎篇(持續更新)

目錄 本文分兩篇&#xff0c;進階篇點擊&#xff1a;C#基礎與進階擴展合集-進階篇 一、基礎入門 Ⅰ 關鍵字 Ⅱ 特性 Ⅲ 常見異常 Ⅳ 基礎擴展 1、哈希表 2、擴展方法 3、自定義集合與索引器 4、迭代器與分部類 5、yield return 6、注冊表 7、不安全代碼 8、方法…

MATLAB中cell函數的用法

cell用法 在MATLAB中&#xff0c;cell 是一種特殊的數據類型&#xff0c;用于存儲不同大小和類型的數據。cell 數組是一種容器&#xff0c;每個元素可以包含任意類型的數據&#xff0c;包括數值、字符串、矩陣、甚至其他的 cell 數組。 以下是 cell 數組的基本語法和示例&…

gitblit自建git倉庫

安裝 java sudo apt-get update sudo apt-get install openjdk-8-jdk # 或者其它你喜歡的版本 驗證&#xff1a; java -version 下載 gitblit https://github.com/gitblit-org/gitblit/releases 解壓/usr/local tar -zxvf gitblit-1.9.3.tar.gz 修改配置文件 nano /usr/local/…

【React】useCallback 使用的說明

文章目錄 useCallback的優缺點優點缺點JavaScript 的內聯優化 使用場景 用了兩年多的react&#xff0c;今天抽空寫點小內容 useCallback的優缺點 緩存了每次渲染時候 inline callback的實例 優點 關鍵點&#xff1a;利用memoize減少無效的re-render&#xff0c;通常配合shouldC…