MongoDB 使用 java mongo 驱动程序自动递增 id 字段?

MongoDB Auto-Incrementing id field with java mongo driver?

一整天我都在努力寻找问题的答案:

“如何在实体中添加自动递增的“id”字段class?”.

我正在使用 Morphia(Mongo 数据库的类型安全 java 库)。经过几个小时的源代码挖掘和谷歌搜索后,我找到了一个 LongIdEntity class in org.mongodb.morphia.utils 包。基于此 class 我实施了以下解决方案。见下文:

城市class:

@Entity
public class City {

    @Id
    private Long id;
}

酒店class:

@Entity
public class Hotel {

    @Id
    private Long id;
}

CityLongIdEntity class:

public class CityLongIdEntity extends LongIdEntity {

    public CityLongIdEntity(Datastore ds) {
        super(ds);
    }

}

HotelLongIdEntity class:

public class HotelLongIdEntity extends LongIdEntity {

    public HotelLongIdEntity(Datastore ds) {
        super(ds);
    }

}

DAO 实现:

CityDAO class:

public class CityDAO extends BasicDAO<City, Long> {

    public CityDAO(Datastore ds) {
        super(ds);
    }

    @Override
    public Key<City> save(City c) {

        if (c.getId() == null) {

            CityLongIdEntity ent = new CityLongIdEntity(getDs());
            getDs().save(ent);
            c.setId(ent.getMyLongId());
        }
        return getDs().save(c);
    }
}

HotelDAO class:

public class HotelDAO extends BasicDAO<Hotel, Long> {

    public HotelDAO(Datastore ds) {
        super(ds);
    }

    @Override
    public Key<Hotel> save(Hotel h) {

        if (h.getId() == null) {

            HotelLongIdEntity ent = new HotelLongIdEntity(getDs());
            getDs().save(ent);
            h.setId(ent.getMyLongId());
        }
        return getDs().save(h);
    }
}

或者您可以在 Github

上查看所有这些代码

UML 图也可用:

所有这些代码都按预期工作,我很高兴,但我有几个问题:

请发表您的意见。

我们需要某些实体的数字 ID,但我们的实现方式略有不同:

  1. 我们对所有实体使用常规的 ObjectId。如果需要,我们会添加一个数字 ID。
  2. 有一个专用的 AutoIncrementEntity,它为不同的键保存一个计数器——这就是你的 class 名字。
  3. 我们不使用 DAO,而是使用通用的保存方法,我们在其中检查我们是否有一个 class 的实例和一个数字 ID。如果尚未设置该 ID,我们将获取一个并更新 AutoIncrementEntity。 relevant method 目前未使用 - 如果完全不清楚请告诉我,我会完成该代码。

我的实现中还有两件事可能有点令人困惑:

  • 您始终可以提供起始编号,因此我们的数字 ID 可以是 1000、1001、1002...而不是 1、2、3...
  • AutoIncrementEntity 中的键不需要是 class,它也可以是子集。例如,您要对公司内的员工进行编号,那么公司 A 的员工的键为 employee-A,公司 B 的键为 company-B,...