mongodb实现递增(转载)

转载自:https://blog.csdn.net/qq_38258310/article/details/88616821
第一步:自定义一个自增长标识,Java的注解就是一个非常优秀的选择,代码如下

package com.lsm1998.userservice.mongo;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * @作者:刘时明
 * @时间:2019/3/17-11:33
 * @说明:自增长标识
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface GeneratedValue
{
 
}

第二步:创建一个MongoDB文档实体,用来记录每个集合中最近的ID,代码如下:

package com.lsm1998.userservice.mongo;
 
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
 
/**
 * @作者:刘时明
 * @时间:2019/3/17-11:43
 * @说明:保存每个集合最近一次的ID
 */
@Document(collection = "sequence")
public class SequenceID
{
    @Id
    private String id;
    @Field("seq_id")
    private long seqId;
    @Field("coll_name")
    private String collName;
 
    public String getId()
    {
        return id;
    }
 
    public void setId(String id)
    {
        this.id = id;
    }
 
    public long getSeqId()
    {
        return seqId;
    }
 
    public void setSeqId(long seqId)
    {
        this.seqId = seqId;
    }
 
    public String getCollName()
    {
        return collName;
    }
 
    public void setCollName(String collName)
    {
        this.collName = collName;
    }
}

第三步:实现一个自定义的MongoDB保存监听器,代码如下:

package com.lsm1998.userservice.mongo;
 
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;
 
/**
 * @作者:刘时明
 * @时间:2019/3/17-11:35
 * @说明:保存监听器
 */
@Component
public class SaveMongoEventListener extends AbstractMongoEventListener<Object>
{
    @Autowired
    private MongoTemplate mongoTemplate;
 
    /**
     * onBefore代表前置处理
     * @param event
     */
    @Override
    public void onBeforeConvert(BeforeConvertEvent<Object> event)
    {
        Object source = event.getSource();
        if (source != null)
        {
            // 当写一个字段的时候触发回调
            ReflectionUtils.doWithFields(source.getClass(),(field)->
            {
                // 使用反射设置字段可以改变
                ReflectionUtils.makeAccessible(field);
                // 判断是否有自增标识
                if(field.isAnnotationPresent(GeneratedValue.class))
                {
                    field.set(source,getNextId(source.getClass().getSimpleName()));
                }
            });
        }
    }
 
    /**
     * 给定集合名,将之中的seqId自增一次,并返回
     * @param collName
     * @return
     */
    private long getNextId(String collName)
    {
        Query query = new Query(Criteria.where("collName").is(collName));
        Update update = new Update();
        update.inc("seqId", 1);
        // findAndModify是原子操作,避免并发问题
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.upsert(true);
        options.returnNew(true);
        SequenceID seqId = mongoTemplate.findAndModify(query, update, options, SequenceID.class);
        return seqId.getSeqId();
    }

}

最后自行测试就可以了,只要在文档实体类的ID字段加上@GeneratedValue注解即可,当然,ID字段的属性也需要是Long类型,如果你想指定其他数值,例如int,则需要稍加修改。

总结:实现MongDB主键自增的关键在于AbstractMongoEventListener,这是Spring提供的关于整合MongoDB的处理监听器,它提供了一些前置、后置的处理方法,类似于MySQL中的触发器,都有AOP的意思。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值