MongoDB 要求你为所有的文档设置一个 _id 字段。如果你没有提供一个 id,Mongo 驱动程序就会分配一个带有生成值的 ObjectId。当你使用 MappingMongoConverter 时,某些规则规定了如何将 Java 类中的属性映射到这个 _id 字段:
用 @Id(org.springframework.data.annotation.Id)注解修饰的属性或字段将被映射到 _id 字段。
一个没有被注释修饰(如 @Id),但是名称为 id 的属性或字段将被映射到 _id 字段。
下面概述了在使用 MappingMongoConverter(MongoTemplate 的默认映射转换器)时,对映射到文档 _id 字段的属性进行了哪些类型转换:
如果可能的话,通过使用 Spring 的 Converter<String, ObjectId>,将 Java 类中声明为 String 的 id 属性或字段转换为 ObjectId 类型并存储。有效的转换规则被委托给 MongoDB Java 驱动。如果它不能被转换为 ObjectId 类型,那么该值将作为字符串存储在数据库中。
通过使用 Spring 的 Converter<BigInteger, ObjectId>,将 Java 类中声明为 BigInteger 的 id 属性或字段转换为 ObjectId 类型并存储。
如果 Java 类中没有前几组规则中指定的字段或属性,驱动程序会自动生成一个隐含的 _id 字段,但不会映射到 Java 类的属性或字段。
在查询和更新时,MongoTemplate 使用与前面的规则相对应的转换器来保存文件,这样在你的查询中使用的字段名和类型就能与你的领域类中的内容相匹配。
有些环境需要采用定制的方法来映射 Id 值,例如存储在 MongoDB 中的数据没有经过 Spring Data 映射层。文档可以包含 _id 值,可以用 ObjectId 或 String 表示。将文档(document)从存储区读取回域类型工作正常。由于隐含的 ObjectId 转换,通过其 id 查询文档会很麻烦。因此不能以这种方式检索文档。对于这些情况,@MongoId 注解提供了对实际 id 映射尝试的更多控制。
使用 @MongoId 注解进行 _id 映射:
public class PlainStringId { // id 被视为 String,无需进一步转换 @MongoId private String id; } public class PlainObjectId { // id 被当作 ObjectId 处理 @MongoId private ObjectId id; } public class StringToObjectId { // 如果给定的 String 是一个有效的 ObjectId 十六进制,id 将被视为 ObjectId,否则视为 String @MongoId(FieldType.OBJECT_ID) private String id; }