前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring-data-mongodb之自增ID实现

spring-data-mongodb之自增ID实现

作者头像
猿天地
发布2018-04-03 12:27:53
2.5K0
发布2018-04-03 12:27:53
举报
文章被收录于专栏:猿天地猿天地

来源:猿天地

链接:http://cxytiandi.com/blog/detail/1897

用了mongodb之后要是问我mongo和mysql的区别在哪里?第一点我就会想到的是没有自增ID,mongo里面是ObjectId。今天我们就自己来实现自增的ID。

像mysql这种数据库是内部实现了自增ID,今天我们要自己实现一个,不知道大家有没有具体的思路。

当然mongodb官网上也提供了一种实现的方法,就是自定义一个获取自增ID的方法,然后每次插入的时候就去获取下一个ID,再插入到集合中。

我们既然用了spring-data-mongodb这个框架,就要基于这个框架来实现一套逻辑,而且每次插入都要自己去手动的调用方法获取一次ID,是不是太繁琐了。

我们用的是监听的模式,在数据插入到集合之前,我们通过反射将ID设置到保存的对象中,来实现自动设置,对写代码的人来说完全透明。

首先我们定义一个用于存储每个集合的ID记录,记录每个集合的自增ID到了多少。

代码语言:javascript
复制
@Document(collection = "sequence")
public class SequenceId {   
    @Id
    private String id;    
    @Field("seq_id")    
    private long seqId;    
    @Field("coll_name")    
    private String collName;

}

接下来定义我们测试的实体类,注意自增ID的类型不要定义成Long这种包装类,mongotemplate的源码里面对主键ID的类型有限制。

代码语言:javascript
复制
@Documentpublic class Student {    
    @GeneratedValue
    @Id
    private long id;    
    private String name;
}

下面我们定义个注解来标识此字段要自动增长ID,有些场景下可能不需要自动增长,需要自动增长的时候我们加上这个注解。

代码语言:javascript
复制
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface GeneratedValue {

}

接下来就是实现自动注入ID的监听器了,需要配置让spring管理

代码语言:javascript
复制
<bean class="com.cxytiandi.mongo.autoid.SaveMongoEventListener"></bean>
代码语言:javascript
复制
public class SaveMongoEventListener extends AbstractMongoEventListener<Object> {
    @Resource
    private MongoTemplate mongoTemplate;    @Override
    public void onBeforeConvert(final Object source) {        
        if(source != null) {            
            ReflectionUtils.doWithFields(source.getClass(), 
                    new ReflectionUtils.FieldCallback() {
                public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {                    ReflectionUtils.makeAccessible(field);                    if (field.isAnnotationPresent(GeneratedValue.class)) {                        //设置自增ID
                        field.set(source, getNextId(source.getClass().getSimpleName()));
                }
               }
            });
        }
   }
 /**
  * 获取下一个自增ID
  * @author yinjihuan
  * @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);     
    FindAndModifyOptions options = new FindAndModifyOptions();
    options.upsert(true);
    options.returnNew(true);     
    SequenceId seqId = mongoTemplate.findAndModify(query, update, options, SequenceId.class);     return seqId.getSeqId();
 }

}

findAndModify()是原子操作,所以不用担心并发问题

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 猿天地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档