如何映射 MongoDB 的 _id 字段?

在 Spring Data MongoDB 中,将 Java POJO 的字段映射到 MongoDB 文档的 _id 字段非常直接,主要通过 @Id 注解(org.springframework.data.annotation.Id)来完成。

以下是映射 MongoDB _id 字段的几种常见方式和关键点:

  1. 使用 String 类型作为 ID (最常见):

    • @Id 注解的字段类型是 String 时,Spring Data MongoDB 会将其视为 MongoDB ObjectId 的字符串表示形式。
    • 如果在保存新文档时此 String 字段为 null ,MongoDB Java 驱动程序会自动生成一个新的 ObjectId,然后 Spring Data MongoDB 会将其转换为字符串并赋值给该字段。
    • 这是最推荐和最方便的方式,因为字符串形式的 ID 更容易在 API、URL 和日志中使用。
    java 复制代码
    import org.springframework.data.annotation.Id;
    import org.springframework.data.mongodb.core.mapping.Document;
    
    @Document(collection = "my_entities")
    public class MyEntity {
    
        @Id
        private String id; // 将映射到 MongoDB 的 _id 字段
    
        private String name;
    
        // Constructors, getters, setters
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    当你保存一个新的 MyEntity 实例且 id 字段为 null 时:

    java 复制代码
    MyEntity entity = new MyEntity();
    entity.setName("Test Entity");
    mongoTemplate.save(entity); // entity.getId() 现在会有一个自动生成的 ObjectId 字符串
    System.out.println(entity.getId()); // 例如:"60c72b941f4b1a3e4c8e4f3a"
  2. 使用 org.bson.types.ObjectId 类型作为 ID:

    • 你可以直接使用 MongoDB BSON库提供的 ObjectId 类型。
    • 同样,如果在保存新文档时此 ObjectId 字段为 null ,驱动程序会自动生成一个新的 ObjectId
    java 复制代码
    import org.bson.types.ObjectId;
    import org.springframework.data.annotation.Id;
    import org.springframework.data.mongodb.core.mapping.Document;
    
    @Document(collection = "products")
    public class Product {
    
        @Id
        private ObjectId id; // 直接使用 ObjectId 类型
    
        private String productName;
    
        // Constructors, getters, setters
        public ObjectId getId() {
            return id;
        }
    
        public void setId(ObjectId id) {
            this.id = id;
        }
    
        public String getProductName() {
            return productName;
        }
    
        public void setProductName(String productName) {
            this.productName = productName;
        }
    }
  3. 使用其他 Java 类型作为 ID (例如 Long, BigInteger):

    • 你也可以使用其他原始类型或对象类型(如 Long, BigInteger)作为 _id
    • 重要 : 如果使用这些类型,MongoDB 不会自动为你生成 ID 。你必须在保存文档之前自己提供一个唯一的 ID 值。如果插入时该字段为 null (对于对象类型) 或默认值 (对于原始类型且你未设置),可能会导致错误或意外行为,具体取决于驱动程序和服务器版本。
    • 这种方式适用于你有外部系统生成 ID,或者 ID 具有特定业务含义的情况。
    java 复制代码
    import org.springframework.data.annotation.Id;
    import org.springframework.data.mongodb.core.mapping.Document;
    import java.math.BigInteger;
    
    @Document(collection = "items")
    public class Item {
    
        @Id
        private Long itemId; // 使用 Long 类型,需要自己保证唯一性并赋值
    
        // 或者
        // @Id
        // private BigInteger itemId; // 使用 BigInteger,需要自己保证唯一性并赋值
    
        private String description;
    
        // Constructors, getters, setters
        public Long getItemId() {
            return itemId;
        }
    
        public void setItemId(Long itemId) {
            this.itemId = itemId;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    }

    使用自定义ID时:

    java 复制代码
    Item item = new Item();
    item.setItemId(12345L); // 必须手动设置 ID
    item.setDescription("Custom ID Item");
    mongoTemplate.save(item);
  4. Java 字段名不一定是 "id":

    • @Id 注解的 Java 字段的名称可以不是 id。Spring Data MongoDB 依然会将其映射到 MongoDB 文档中的 _id 字段。
    java 复制代码
    import org.springframework.data.annotation.Id;
    import org.springframework.data.mongodb.core.mapping.Document;
    
    @Document(collection = "books")
    public class Book {
    
        @Id
        private String bookIsbn; // Java 字段名为 "bookIsbn",但它映射到 MongoDB 的 _id
    
        private String title;
    
        // Getters and setters
        public String getBookIsbn() {
            return bookIsbn;
        }
    
        public void setBookIsbn(String bookIsbn) {
            this.bookIsbn = bookIsbn;
        }
        // ...
    }

关键点总结:

  • @Id 注解 : 是将 Java 字段标记为 MongoDB _id 的核心。
  • 自动生成 :
    • 仅当 @Id 字段类型为 Stringorg.bson.types.ObjectId,并且在插入新文档时该字段值为 null 时,ID 才会由 MongoDB 驱动自动生成。
    • 其他类型(如 Long, Integer, BigInteger)需要你在应用程序中手动赋值并确保其唯一性。
  • 不可变性 : MongoDB 中的 _id 字段一旦设置,就不能被修改。尝试更新 _id 会导致操作失败或创建一个新文档(取决于操作类型)。
  • 唯一性 : _id 在其集合中必须是唯一的。MongoDB 会自动为 _id 字段创建唯一索引。
  • @Field("_id") : 通常不需要。@Id 注解本身就隐含了该 Java 字段映射到 BSON 文档的 _id 键。显式使用 @Field("_id") 是多余的。

选择哪种 ID 类型取决于你的具体需求:

  • String (ObjectId 字符串): 通用,方便,推荐用于大多数场景。
  • ObjectId : 如果你需要在 Java 代码中直接操作 ObjectId 对象(例如,获取时间戳部分)。
  • Long / BigInteger / 其他自定义类型: 当 ID 有特定业务含义或由外部系统生成时。

在大多数 Spring Boot 应用中,使用 String 类型并让 MongoDB 自动生成 ObjectId 是最简单和最常见的做法。

相关推荐
lifewange13 分钟前
数据库索引里面的游标是什么?
数据库·oracle
PhDTool34 分钟前
计算机化系统验证(CSV)的前世今生
数据库·安全·全文检索
banpu38 分钟前
Spring相关
数据库·spring·sqlserver
老年DBA41 分钟前
Ora2Pg 迁移Oracle至 PostgreSQL 之实战指南
数据库·postgresql·oracle
我是苏苏44 分钟前
MSSQL04: SQLserver的用户权限管理
数据库
l1t1 小时前
达梦数据库和Oracle兼容性和性能比较
数据库·sql·oracle·达梦
lkbhua莱克瓦241 小时前
基础-事务
开发语言·数据库·笔记·mysql·事务
weixin_436525071 小时前
NestJS-TypeORM QueryBuilder 常用 SQL 写法
java·数据库·sql
Cosolar1 小时前
MySQL EXPLAIN 执行计划分析:能否查看 JOIN 关联顺序
数据库·后端·mysql
micromicrofat2 小时前
【MongoDB】WSL2访问宿主机的MongoDB
数据库·mongodb