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

时间:2015-01-27 22:16:27

标签: java dao mongodb-java morphia

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

"如何添加自动递增" id"实体类中的字段?"

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

城市类:

@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 class:

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图也可用:enter image description here

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

  • 如您所见,对于每个实体,我需要创建其他实体,例如:对于实体City我创建了CityLongIdEntity(此实体是自动递增功能的关键部分)。在这种情况下,如果我的应用有20个实体(CityAddressHotelUserRoomOrder等)我需要创建40个课程!我很害怕,但我认为这将是&#34; Code smell&#34;。 我是对的吗?
  • 此外,Entity并不了解EntityNameLongIdEntityEntityNameLongIdEntity不知道谁是Entity。并且只有特定的EntityDAO类结合使用这些类。好吗? 或者又是代码味道
  • 每个EntityDAO类覆盖扩展BasicDAO类并覆盖方法save()。不同save()类的覆盖方法DAO之间的差异很小。我害怕。这是代码重复和代码再次闻到。 我是对的

请提供您的意见。

1 个答案:

答案 0 :(得分:2)

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

  1. 我们在所有实体上使用常规ObjectId。如果需要,我们会添加数字ID。
  2. 有一个专用的AutoIncrementEntity,它为不同的密钥设置了一个计数器 - 这将是您的班级名称。
  3. 我们不使用DAO,而是使用泛型保存方法,我们检查是否有一个带有数字ID的类的实例。如果该ID尚未设置,我们将获取一个ID并更新AutoIncrementEntity。 relevant method目前尚未使用 - 请告知我是否完全不清楚并且我将完成该代码。
  4. 我的实施还有两件事情,可能有点令人困惑:

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