java mongodb 自增_SpringBoot+mongoDB实现id自增

本文介绍了如何在Spring Boot应用中结合MongoDB实现自增ID,详细讲解了自定义注解、数据表存储、监听类的实现以及在对象中应用自增ID的步骤。
摘要由CSDN通过智能技术生成

这段时间给朋友做了一个微信小程序,顺便练习一下spring boot,虽然项目使用的是JPA+MySQL,但是好奇尝试了一下MongoDB实现自增ID,虽然MongoDB很少有自增ID的需求(在分布式环境中,多个机器同步一个自增ID不但费时且费力,MongoDB从一开始就是设计用来做分布式数据库的,处理多个节点是一个核心要求,而ObjectId在分片环境中要容易生成的多),但是需求是多变的,难免会遇到需要自增的需求。

QQ%E6%88%AA%E5%9B%BE20180416140928-300x71.png

MongoDB有默认的ObjectId,是一个12字节的 BSON 类型字符串。按照字节顺序,依次次代表:

4字节:UNIX时间戳

3字节:表示运行MongoDB的机器

2字节:表示生成此_id的进程

3字节:由一个随机数开始的计数器生成的值

Spring boot中可以使用MongoTemplate操作MongoDB,但是不能自增ID,只能手动实现:

1).自定义注解用于标识需要自增的Field.

package com.example.annotation;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface AutoIncKey {}

2).创建数据表存储当前的id号

id的自增进度需要一个数据表存储(只是存储当前id号数据,可以不用数据库而用其他形式)

@Document(collection = "inc")

public class IncInfo {

@Id

private String id;// 主键

@Field

private String collName;// 需要自增id的集合名称(这里设置为MyDomain)

@Field

private Integer incId;// 当前自增id值

// 省略getter、setter

3).实现监听类

监听器用于监听Mongo Event,该类继承AbstractMongoEventListener类,因为我们需要在JAVA对象转换成数据库对象的时候操作id字段实现id自增,所以覆盖onBeforeConvert方法(详见spring-data文档,https://docs.spring.io/spring-data/data-document/docs/current/reference/html/,5.11节)

package com.example.listener;

import java.lang.reflect.Field;

import com.example.annotation.AutoIncKey;

import com.example.domain.MyDomain;

import com.example.domain.IncInfo;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.mongodb.core.FindAndModifyOptions;

import org.springframework.data.mongodb.core.MongoTemplate;

import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;

import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;

import org.springframework.data.mongodb.core.query.Criteria;

import org.springframework.data.mongodb.core.query.Query;

import org.springframework.data.mongodb.core.query.Update;

import org.springframework.stereotype.Component;

import org.springframework.util.ReflectionUtils;

@Component

public class SaveEventListener extends AbstractMongoEventListener{

private static final Logger logger= LoggerFactory.getLogger(SaveEventListener.class);

@Autowired

private MongoTemplate mongo;

@Override

public void onBeforeConvert(BeforeConvertEvent event) {

logger.info(event.getSource().toString());

MyDomain source=(MyDomain)event.getSource();

if (source != null) {

ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {

public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {

ReflectionUtils.makeAccessible(field);

// 如果字段添加了我们自定义的AutoIncKey注解

if (field.isAnnotationPresent(AutoIncKey.class)) {

// 设置自增ID

field.set(source, getNextId(source.getClass().getSimpleName()));

}

}

});

}

}

private Integer getNextId(String collName) {

Query query = new Query(Criteria.where("collName").is(collName));

Update update = new Update();

update.inc("incId", 1);

FindAndModifyOptions options = new FindAndModifyOptions();

options.upsert(true);

options.returnNew(true);

IncInfo inc= mongo.findAndModify(query, update, options, IncInfo.class);

return inc.getIncId();

}

}

4).在我们的对象中id字段上添加注解

@Id

@AutoIncKey

private Integer id=0;

至此就实现了Mongodb的自增id。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值