Mongodb自增id实现

Mongodb自增id

具体场景

一个服务检测配置的数据库存储,可以有多个配置,为了让配置文件测查询时按照顺序排序,选择了自增id的设置,做法也很不是非常的复杂,可以通过自定义注解来实现

自定义注解实现

添加注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoIncKey

}
监听注解

定义监听类SaveMongoEventListener,重写save方法

/**
 * .重载 方法
 * 
 * @param event
 * BeforeConvertEvent
 */
@Override
public void onBeforeConvert(BeforeConvertEvent<Object> event) {
    final Object source = event.getSource();
    if (source != null) {
        ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {
            @Override
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                ReflectionUtils.makeAccessible(field);
                // 如果字段添加了我们自定义的AutoIncKey注解
                if (field.isAnnotationPresent(AutoIncKey.class) && field.get(source) instanceof Number && field.getLong(source) == 0) {
                    // 设置自增ID
                  field.set(source,getNextConfigId(source.getClass().getSimpleName()));
                }
            }
        });
    }
}

/**
 * 获取下一个自检服务配置自增id.
 * @param collName
 * @return
*/
private Long getNextConfigId(String collName) {
    Update update = new Update();
    update.inc("seqId", 1);
    FindAndModifyOptions options = new FindAndModifyOptions();
    options.upsert(true);
    options.returnNew(true);
    Query query = new Query(Criteria.where("collName").is(collName));
    SequenceId seqId = cMongoTemplate.findAndModify(query, update, options, SequenceId.class);
    return seqId.getSeqId();
}
使用注解
/**
 * 自检服务配置.
 * @author 杀马龙
 *
 */
@Data
@Document(collection = "weilong_config")
public class SelfCheckConfig {
    @Id
    @Field("_id")
    @AutoIncKey
    private long id;
    //设置名称
    private String name;
    private boolean enable;
    //类型选取
    private TypeCheck typeCheck;
    //相同名称检测
    private TitleCheck titleCheck;
    //热门资源用户画像检测
    private PortraitCheck portraitCheck;
    //字段完整性检测
    private FieldCheck fieldCheck;
    //上下线状态检测
    private StatusCheck statusCheck;
}
弊端

使用这种方式存在一点问题,不管你保存还是新增,他都会新增一个新的id,导致存储数据时,同一配置信息有多个id,鉴于这种情况,我选择了在新增的时候获取到最大的id,然后设置id保存,保存的时候,直接继承原始id

非注解实现

新增操作
/**
 * 添加配置信息.
 * 
 * @param config 配置
 * @param col 表名
 * @return
 */
public Boolean addConfig(SelfCheckConfig config, String col) {
    long id = getNextConfigId(col);
    config.setId(id);
    mongoTemplate.save(config);
    return true;
}

总结

mongodb作为一个NoSql的数据库,一般情况下id都是自动生成的,大多数情况也都是通过md5码编码多个字段的字符串集合,生成唯一id,自增id官方没有做我觉得是有一定道理的,mongodb属于分布式数据库,几台机器要互相协调拿最新的id,就需要有一个锁来进行网络协调,相对起来就很低效了。

要按照插入顺序排序的话最好还是新增一个创建时间和修改时间,既不费时,又不费力。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值