【问题标题】:MongoDB Auto-Incrementing id field with java mongo driver?带有java mongo驱动程序的MongoDB Auto-Incrementing id字段?
【发布时间】:2015-01-27 22:16:27
【问题描述】:

我整天都在试图找到这个问题的答案:

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

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

城市等级:

@Entity
public class City {

    @Id
    private Long id;
}

酒店等级:

@Entity
public class Hotel {

    @Id
    private Long id;
}

CityLongIdEntity 类:

public class CityLongIdEntity extends LongIdEntity {

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

}

HotelLongIdEntity 类:

public class HotelLongIdEntity extends LongIdEntity {

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

}

DAO 实施:

CityDAO 类:

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 类:

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图也可以:

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

  • 如您所见,我需要为每个实体创建额外的实体,例如:对于实体City,我创建了CityLongIdEntity(该实体是自动递增功能的关键部分)。在这种情况下,如果我的应用程序将有 20 个实体(CityAddressHotelUserRoomOrder 等),我将需要创建 40 个类!我很害怕,但我认为这将是“代码气味”。 我说的对吗
  • 另外,Entity 不知道EntityNameLongIdEntityEntityNameLongIdEntity 不知道Entity 是谁。只有特定的 EntityDAO 类将 ans 组合在一起使用这些类。可以吗? 还是又是代码异味
  • 每个EntityDAO 类覆盖扩展BasicDAO 类并覆盖方法save()。不同DAO 类的覆盖方法save() 之间的差异很小。恐怕。那又是代码重复和代码异味。 我说的对吗

请提供您的意见。

【问题讨论】:

  • 您是否只需要Long 类型的ID?通常在 MongoDB 中,您使用 ObjectId 类型的 id 可以在客户端或服务器端(隐式)生成
  • +1 亚历克斯,每次使用递增的 id 保存也会导致额外的 findAndModify 调用。顺便说一句,Morphia 很好,但不灵活等,在使用了几年 Morphia 之后,我已经切换到 Jackson/MongoJack。

标签: java dao mongodb-java morphia


【解决方案1】:

我们需要在某些实体上使用数字 ID,但我们的实现有点不同:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    • 2020-09-25
    • 2014-02-28
    • 1970-01-01
    • 2016-03-13
    • 2016-02-11
    • 1970-01-01
    相关资源
    最近更新 更多