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,就需要有一个锁来进行网络协调,相对起来就很低效了。
要按照插入顺序排序的话最好还是新增一个创建时间和修改时间,既不费时,又不费力。