菜根乱谭

为MongoDB增加自增长主键生成的功能

每个MongoDB的document都有一个_id字段作为它的第一个属性,这个值通常是一个BSON对象id,因此,这个id对于集合中的每个成员都是唯一的,如果用户插入一个document没有提供一个id,数据库将自动生成一个id,并存储在_id字段。   
   The BSON ObjectId Datatype   
一个BSON ObjectID是由12个字节组成:4字节时间+3字节机器id+2字节进程id+3字节的数字
{ "_id" : ObjectId("4c691e72ed2a47b462dfa806") }


有时候我们的应用中需要自增长的数字型主键,MongoDB在这方面并没有给我们提供支持,我们需要加以改造,使其具有自增长主键生成的功能。此次的功能改造,依赖的是morphia开源项目(MongoDB在java语言上的ORM实现,https://code.google.com/p/morphia/),直接上代码吧。


首先定义一个保存各个 collection的主键增量值的系统配置collection:StoredSeqence

java 代码

  1. /**  

  2.  * MongoDB自增长主键维护队列,类似于MSSQL,Oracle维护主键的方式  

  3.  *   

  4.  * @author yongtree  

  5.  * @date 2011-1-17 下午06:58:05  

  6.  * @version 1.0  

  7.  */  

  8. @Entity(noClassnameStored=true)   

  9. public class StoredSeqence implements Serializable {   

  10.   

  11.     private static final long serialVersionUID = 1L;   

  12.   

  13.     @Id  

  14.     String collName;   

  15.   

  16.     Long value;   

  17.        

  18.   

  19.     public StoredSeqence(){   

  20.            

  21.     }   

  22.        

  23.     public StoredSeqence(String collName) {   

  24.         this.collName = collName;   

  25.     }   

  26.   

  27.     public Long getValue() {   

  28.         return value;   

  29.     }   

  30.   

  31.     public void setValue(Long value) {   

  32.         this.value = value;   

  33.     }   

  34.   

  35.     public String getCollName() {   

  36.         return collName;   

  37.     }   

  38.   

  39.     public void setCollName(String collName) {   

  40.         this.collName = collName;   

  41.     }   

  42.   

  43.        

  44.   

  45.        

  46. }   

然后定义一个实体的基类,在基类中处理主键生成。

java 代码

  1. /**  

  2.  * 自增长数字类型主键的Mongo实体  

  3.  *   

  4.  * @author yongtree  

  5.  * @date 2011-1-17 下午04:11:04  

  6.  * @version 1.0  

  7.  */  

  8. public abstract class LongPKMongoEO extends BaseMongoEO {   

  9.   

  10.     @Id  

  11.     Long _id;   

  12.   

  13.     @Transient  

  14.     protected Datastore ds;   

  15.        

  16.        

  17.   

  18.     public void setDs(Datastore ds) {   

  19.         this.ds = ds;   

  20.     }   

  21.   

  22.     @PrePersist  

  23.     void prePersist() {   

  24.            

  25.         //自增性主键的处理   

  26.            

  27.         if (_id == null) {   

  28.             String collName = ds.getCollection(getClass()).getName();   

  29.             Query<StoredSeqence> q = ds.find(StoredSeqence.class, "_id",   

  30.                     collName);   

  31.             StoredSeqence ss = q.get();   

  32.             if(ss==null){//不存在该实体的注册,则新创建一个   

  33.                 ss = new StoredSeqence(collName);   

  34.                 ss.setValue(1l);   

  35.             }else{   

  36.                 ss.setValue(ss.getValue()+1);   

  37.             }   

  38.             ds.save(ss);   

  39.             _id=ss.value;   

  40.         }   

  41.     }   

  42.   

  43.     public Long getId() {   

  44.         return _id;   

  45.     }   

  46.   

  47. }  



这样自增长主键的生成的主要功能基本上已经完成了,具体如何使用,接下来将根据实际的项目再做介绍,请继续关注我的博客

 

原文:https://www.po-soft.com/hi/yongtree/blog/2157


评论