Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 598|回复: 0

MongoDB Long/Int(长整型)的自增长主键 解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-27 23:21:26 | 显示全部楼层 |阅读模式

    今朝有幸尝芒果,发现自增长ID类型有多种,唯独没有Long/Int。

    一思路:
    1. 自建一个Collection(表,假设名为:IdentityEntity,其中字段:_id, Key, Value,其中_id你懂的,Key:Collection名,需要用Long/Int自增长主键的Collection名,value:Key字段中所存Collection的Long/Int自增长最大值),此表用于存入要用Long/Int自增长主键的Collection信息(为方便举例:XLogs)
    结构自建的Collection, IdentityEntity如下:
    _id        Key      Value
    new Guid()    XLogs      5

    2. 每次往XLogs新增数据时,将当前最大值(5)取出来,然后再加1,我们知道自增长键是无需我们明确Insert的,当然它也一样整个过程都是由Mongo自身框架内部完成。

    3. 既然是内部完成,我们就得实现一小部分代码,让Mongo框架来调用

    二实现:

    1. Mongo框架中的接口:IIdGenerator

     1 #region 程序集 MongoDB.Bson.dll, v1.9.2.235
     2 // E:\Projects\DLL\MongoDB.Bson.dll
     3 #endregion
     4 
     5 using System;
     6 
     7 namespace MongoDB.Bson.Serialization
     8 {
     9     // 摘要: 
    10     //     An interface implemented by Id generators.
    11     public interface IIdGenerator
    12     {
    13         // 摘要: 
    14         //     Generates an Id for a document.
    15         //
    16         // 参数: 
    17         //   container:
    18         //     The container of the document (will be a MongoCollection when called from
    19         //     the C# driver).
    20         //
    21         //   document:
    22         //     The document.
    23         //
    24         // 返回结果: 
    25         //     An Id.
    26         object GenerateId(object container, object document);
    27         //
    28         // 摘要: 
    29         //     Tests whether an Id is empty.
    30         //
    31         // 参数: 
    32         //   id:
    33         //     The Id.
    34         //
    35         // 返回结果: 
    36         //     True if the Id is empty.
    37         bool IsEmpty(object id);
    38     }
    39 }
    View Code

    2. 实现接口,代码:

     1 public class LongIdGenerator<TDocument, TKey> : IIdGenerator where TDocument : class
     2     {
     3         private static LongIdGenerator<TDocument, TKey> _instance = new LongIdGenerator<TDocument, TKey>();
     4         public static LongIdGenerator<TDocument, TKey> Instance { get { return _instance; } }
     5 
     6         public object GenerateId(object container, object document)
     7         {
     8             TKey id = default(TKey);
     9             var collection = container as MongoCollection<TDocument>;
    10             if (null != collection)
    11             {
    12                 var mongoDB = collection.Database; 
    13                 var idColl = mongoDB.GetCollection<IdentityEntity<TKey>>("IdentityEntity");
    14                 var keyName = document.GetType().Name;
    15                 id  = RealGenerateId(idColl, keyName) ;
    16             }
    17             return id;
    18         }
    19 
    20         private TKey RealGenerateId(MongoCollection<IdentityEntity<TKey>> idColl, string keyName)
    21         {
    22             TKey id;
    23             var idQuery = new QueryDocument("Key", BsonValue.Create(keyName));
    24             var idBuilder = new UpdateBuilder();
    25             idBuilder.Inc("Value", 1);
    26 
    27             var args = new FindAndModifyArgs();
    28             args.Query = idQuery;
    29             args.Update = idBuilder;
    30             args.VersionReturned = FindAndModifyDocumentVersion.Modified;
    31             args.Upsert = true;
    32 
    33             var result = idColl.FindAndModify(args);
    34             if (!string.IsNullOrEmpty(result.ErrorMessage))
    35             {
    36                 throw new Exception(result.ErrorMessage);
    37             }
    38             id = result.GetModifiedDocumentAs<IdentityEntity<TKey>>().Value;
    39             return id;
    40         }        
    41 
    42         public bool IsEmpty(object id)
    43         {
    44             if (null == id)
    45             {
    46                 return false;
    47             }
    48             return true;
    49         }
    50     }

    2.2. 从上代码看我们知道,先要了解对Mongodb Collection的增,改,查等基本操作,然后理解“思路”中所提内容。注意Collection IdentityEntity在代码中已写死,当他不存在时第一次运行会自动新增此Collection。

    三应用
    到此已完成代码实现。即然实现,那么开始谈应用:
    方式1.

     1  public class XLogs : BaseLog, IEntity<long>
     2     {
     3         //应用:在long自增长键上加此特性
     4         [BsonId(IdGenerator = typeof(LongIdGenerator<XLogs>))]
     5         public long Id { get; set; }
     6 
     7         public byte Status { get; set; }
     8       
     9         public string CreatedBy { get; set; }
    10       
    11         public System.DateTime CreatedDate { get; set; }
    12         
    13         public string Remark { get; set; }
    14         
    15         public decimal Amount { get; set; }
    16     }

    方式2. 注册的方式,在数据进Collection XLogs之前,就要运行它

    1 BsonClassMap.RegisterClassMap<XLogs>(rc =>
    2             {
    3                 rc.AutoMap();
    4                 rc.SetIdMember(rc.GetMemberMap(c => c.Id));
    5                 rc.IdMemberMap.SetIdGenerator(LongIdGenerator<XLogs, long>.Instance);
    6             });

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 14:14 , Processed in 2.105843 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表