zoukankan      html  css  js  c++  java
  • 基于官方驱动封装mongodb

    还是一如既往先把结构图放出来,上上个版本添加了redis的缓存,但是不满足我的需求,因为公司有项目要求是分布式所以呢,这里我就增加了mongoDb进行缓存分布式,好了先看结构图(1)。

    总的来说比较蛋疼,因为从来没有使用过mongoDB,从安装,到转为windows服务,设置权限等等,好吧这都是题外话。

    在写这个MongoDB版本的时候遇到的一些问题,我先总结下:

    1.MongoDb版本是官网最新版3.4.4,官方驱动为2.4.3,首先我的项目是以GUID做为主键,在往MongonDB中插入时遇到的是将GUID生成了MongoDB的LUUID格式产生了这样的格式(2)并且和我的数据库不同(3)当然redis也不同(4)。

    a)带着问题我们去解决查了文档发现原来因为bson的键要标识成GUID,并且格式要转为string,既然知道问题了就去解决找到我的GUID主键,如下图(5):

    在主键上加上 [BsonId(IdGenerator = typeof(GuidGenerator)), BsonRepresentation(BsonType.String)]这段就可以了,看了下效果确实可以了(6)。

    2.但是在测试过程中查询的时候却找不到,一查原来我的数据库redis的id值都不一样,这又是怎么回事?

    b)原来mongoDB生成的GUID和C#生成的GUID的进制是不一样的,为了解决这个问题,Google了一下,找到了一个脚本,把这个js脚本放在mongoDB里面执行一下,然后生成的GUID就和数据库的一样了。如图(7):

    然后生成的_id就和我数据redis的一样了。(8)(9)

    解决完成这些问题后开始写自己的封装类。

    希望大家多给出建议,博主也是第一次玩mongoDB,如果有好的学习资源也请推荐给博主。

    第一步创建连接:

    using MongoDB.Driver;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.MongoDbCache.MongoDbCommon
    {
        public class MongoDbManager
        {
            private static IMongoDatabase db = null;
            private static readonly object locker = new object();
            /// <summary>
            /// 使用单列模式创建连接
            /// </summary>
            /// <returns></returns>
            public static IMongoDatabase CreateDb()
            {
                if (db == null)
                {
                    lock (locker)
                    {
                        if (db == null)
                        {
                            MongoClient Client = new MongoClient(MongoDbConfig.Host);
                            db = Client.GetDatabase(MongoDbConfig.DataBase);
                        }
                    }
                }
                return db;
            }
        }
    }
    View Code

    第二步创建DB:

    using MongoDB.Driver;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.MongoDbCache.MongoDbCommon
    {
        public class MongoDbBase
        {
            private IMongoDatabase db = null;
            public IMongoDatabase Db { get => db; }
            public MongoDbBase()
            {
                db = MongoDbManager.CreateDb();
            }
        }
    }
    View Code

    然后呢献上自己的封装helper:

    using KuRuMi.Mio.DoMain.MongoDbCache.MongoDbCommon;
    using MongoDB.Bson;
    using MongoDB.Driver;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.MongoDbCache.MongoDbCache
    {
        /// <summary>
        /// MongoDb缓存
        /// </summary>
        public sealed class MongoDbCacheService : MongoDbBase
        {
            #region 同步
            #region 增加
            /// <summary>
            /// 保存单个对象
            /// </summary>
            /// <param name="Root"></param>
            /// <returns></returns>
            public bool AddSignleObject<TAggregateRoot>(TAggregateRoot Root)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    collection.InsertOne(Root);
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
    
            }
            /// <summary>
            /// 批量保存多个对象
            /// </summary>
            /// <param name="Root"></param>
            /// <returns></returns>
            public bool AddManyObject<TAggregateRoot>(List<TAggregateRoot> Root)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    collection.InsertMany(Root);
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
    
            }
            #endregion
    
            #region 删除
            /// <summary>
            /// 删除单个记录
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="parameter"></param>
            /// <returns></returns>
            public int DeleteSingleIndex<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    return (int)collection.DeleteOne(filter).DeletedCount;
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            #endregion
    
            #region 查询
            /// <summary>
            /// 查询单条记录
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="parameter"></param>
            /// <returns></returns>
            public TAggregateRoot FindSingleIndex<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    return collection.Find(filter).FirstOrDefault();
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            /// <summary>
            /// 查询整个集合
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="filter"></param>
            /// <returns></returns>
            public List<TAggregateRoot> FindMany<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    return collection.Find(filter).ToList();
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            #endregion
    
            #region 更新
            /// <summary>
            /// 更新单个值
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="filter"></param>
            /// <param name="field"></param>
            /// <param name="parameter"></param>
            /// <returns></returns>
            public int UpdateSingle<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter, string name, string parameter)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    var set = Builders<TAggregateRoot>.Update.Set(name, parameter);
                    return (int)collection.UpdateOne(filter, set).ModifiedCount;
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            /// <summary>
            /// 更新多个值
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="filter"></param>
            /// <param name="Root"></param>
            /// <param name="property"></param>
            /// <param name="replace"></param>
            public int UpdateMany<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter, TAggregateRoot Root, List<string> property = null, bool replace = false)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    var type = Root.GetType();
                    //修改集合
                    var list = new List<UpdateDefinition<TAggregateRoot>>();
                    foreach (var propert in type.GetProperties())
                    {
                        if (propert.Name.ToLower() != "id")
                        {
                            try
                            {
                                if (property == null && property.Count < 1 || property.Any(o => o.ToLower() == propert.Name.ToLower()))
                                {
                                    var replaceValue = propert.GetValue(Root);
                                    if (replaceValue != null)
                                        list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
                                    else if (replace)
                                        list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
                                }
                            }
                            catch (Exception)
                            {
                                if (property == null)
                                {
                                    var replaceValue = propert.GetValue(Root);
                                    if (replaceValue != null)
                                        list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
                                    else if (replace)
                                        list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
                                }
                            }
                            
                        }
                    }
                    if (list.Count > 0)
                    {
                        var builders = Builders<TAggregateRoot>.Update.Combine(list);
                        return (int)collection.UpdateOne(filter, builders).ModifiedCount;
                    }
                    return 0;
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            #endregion
            #endregion
    
            #region 异步
            #region 增加
            /// <summary>
            /// 异步保存单个对象
            /// </summary>
            /// <param name="Root"></param>
            /// <returns></returns>
            public bool AddSignleObjectAsync<TAggregateRoot>(TAggregateRoot Root)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    collection.InsertOneAsync(Root);
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
    
            }
            /// <summary>
            /// 批量保存多个对象
            /// </summary>
            /// <param name="Root"></param>
            /// <returns></returns>
            public bool AddManyObjectAsync<TAggregateRoot>(List<TAggregateRoot> Root)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    collection.InsertManyAsync(Root);
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
    
            }
            #endregion
    
            #region 删除
            /// <summary>
            /// 异步删除单个记录
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="parameter"></param>
            /// <returns></returns>
            public int DeleteSingleIndexAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    return (int)collection.DeleteOneAsync(filter).Result.DeletedCount;
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            #endregion
    
            #region 查询
            /// <summary>
            /// 异步查询单条记录
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="parameter"></param>
            /// <returns></returns>
            public TAggregateRoot FindSingleIndexAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    return collection.FindAsync(filter).Result.FirstOrDefault();
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            /// <summary>
            /// 异步查询整个集合
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="filter"></param>
            /// <returns></returns>
            public List<TAggregateRoot> FindManyAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    return collection.FindAsync(filter).Result.ToList();
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            #endregion
    
            #region 更新
            /// <summary>
            /// 异步更新单个值
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="filter"></param>
            /// <param name="field"></param>
            /// <param name="parameter"></param>
            /// <returns></returns>
            public int UpdateSingleAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter, string name, string parameter)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    var set = Builders<TAggregateRoot>.Update.Set(name, parameter);
                    return (int)collection.UpdateOneAsync(filter, set).Result.ModifiedCount;
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            /// <summary>
            ///异步更新多个值
            /// </summary>
            /// <typeparam name="TAggregateRoot"></typeparam>
            /// <param name="filter"></param>
            /// <param name="Root"></param>
            /// <param name="property"></param>
            /// <param name="replace"></param>
            public int UpdateManyAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter, TAggregateRoot Root, List<string> property = null, bool replace = false)
            {
                try
                {
                    var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
                    var type = Root.GetType();
                    //修改集合
                    var list = new List<UpdateDefinition<TAggregateRoot>>();
                    foreach (var propert in type.GetProperties())
                    {
                        if (propert.Name.ToLower() != "id")
                        {
                            try
                            {
                                if (property == null && property.Count < 1 || property.Any(o => o.ToLower() == propert.Name.ToLower()))
                                {
                                    var replaceValue = propert.GetValue(Root);
                                    if (replaceValue != null)
                                        list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
                                    else if (replace)
                                        list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
                                }
                            }
                            catch (Exception)
                            {
                                if (property == null)
                                {
                                    var replaceValue = propert.GetValue(Root);
                                    if (replaceValue != null)
                                        list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
                                    else if (replace)
                                        list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
                                }
                            }
    
                        }
                    }
                    if (list.Count > 0)
                    {
                        var builders = Builders<TAggregateRoot>.Update.Combine(list);
                       return (int)collection.UpdateOneAsync(filter, builders).Result.ModifiedCount;
                    }
                    return 0;
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            #endregion
            #endregion
        }
    }
    View Code

    最后是脚本文件:

    function HexToBase64(hex) {
        var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        var base64 = "";
        var group;
        for (var i = 0; i < 30; i += 6) {
            group = parseInt(hex.substr(i, 6), 16);
            base64 += base64Digits[(group >> 18) & 0x3f];
            base64 += base64Digits[(group >> 12) & 0x3f];
            base64 += base64Digits[(group >> 6) & 0x3f];
            base64 += base64Digits[group & 0x3f];
        }
        group = parseInt(hex.substr(30, 2), 16);
        base64 += base64Digits[(group >> 2) & 0x3f];
        base64 += base64Digits[(group << 4) & 0x3f];
        base64 += "==";
        return base64;
    }
    
    function Base64ToHex(base64) {
        var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        var hexDigits = "0123456789abcdef";
        var hex = "";
        for (var i = 0; i < 24;) {
            var e1 = base64Digits.indexOf(base64[i++]);
            var e2 = base64Digits.indexOf(base64[i++]);
            var e3 = base64Digits.indexOf(base64[i++]);
            var e4 = base64Digits.indexOf(base64[i++]);
            var c1 = (e1 << 2) | (e2 >> 4);
            var c2 = ((e2 & 15) << 4) | (e3 >> 2);
            var c3 = ((e3 & 3) << 6) | e4;
            hex += hexDigits[c1 >> 4];
            hex += hexDigits[c1 & 15];
            if (e3 != 64) {
                hex += hexDigits[c2 >> 4];
                hex += hexDigits[c2 & 15];
            }
            if (e4 != 64) {
                hex += hexDigits[c3 >> 4];
                hex += hexDigits[c3 & 15];
            }
        }
        return hex;
    }
    
    function UUID(uuid) {
        var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
        var base64 = HexToBase64(hex);
        return new BinData(4, base64); // new subtype 4
    }
    
    function JUUID(uuid) {
        var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
        var msb = hex.substr(0, 16);
        var lsb = hex.substr(16, 16);
        msb = msb.substr(14, 2) + msb.substr(12, 2) + msb.substr(10, 2) + msb.substr(8, 2) + msb.substr(6, 2) + msb.substr(4, 2) + msb.substr(2, 2) + msb.substr(0, 2);
        lsb = lsb.substr(14, 2) + lsb.substr(12, 2) + lsb.substr(10, 2) + lsb.substr(8, 2) + lsb.substr(6, 2) + lsb.substr(4, 2) + lsb.substr(2, 2) + lsb.substr(0, 2);
        hex = msb + lsb;
        var base64 = HexToBase64(hex);
        return new BinData(3, base64);
    }
    
    function CSUUID(uuid) {
        var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
        var a = hex.substr(6, 2) + hex.substr(4, 2) + hex.substr(2, 2) + hex.substr(0, 2);
        var b = hex.substr(10, 2) + hex.substr(8, 2);
        var c = hex.substr(14, 2) + hex.substr(12, 2);
        var d = hex.substr(16, 16);
        hex = a + b + c + d;
        var base64 = HexToBase64(hex);
        return new BinData(3, base64);
    }
    
    function PYUUID(uuid) {
        var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
        var base64 = HexToBase64(hex);
        return new BinData(3, base64);
    }
    
    BinData.prototype.toUUID = function () {
        var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs in older versions of the shell
        var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
        return 'UUID("' + uuid + '")';
    }
    
    BinData.prototype.toJUUID = function () {
        var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs in older versions of the shell
        var msb = hex.substr(0, 16);
        var lsb = hex.substr(16, 16);
        msb = msb.substr(14, 2) + msb.substr(12, 2) + msb.substr(10, 2) + msb.substr(8, 2) + msb.substr(6, 2) + msb.substr(4, 2) + msb.substr(2, 2) + msb.substr(0, 2);
        lsb = lsb.substr(14, 2) + lsb.substr(12, 2) + lsb.substr(10, 2) + lsb.substr(8, 2) + lsb.substr(6, 2) + lsb.substr(4, 2) + lsb.substr(2, 2) + lsb.substr(0, 2);
        hex = msb + lsb;
        var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
        return 'JUUID("' + uuid + '")';
    }
    
    BinData.prototype.toCSUUID = function () {
        var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs in older versions of the shell
        var a = hex.substr(6, 2) + hex.substr(4, 2) + hex.substr(2, 2) + hex.substr(0, 2);
        var b = hex.substr(10, 2) + hex.substr(8, 2);
        var c = hex.substr(14, 2) + hex.substr(12, 2);
        var d = hex.substr(16, 16);
        hex = a + b + c + d;
        var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
        return 'CSUUID("' + uuid + '")';
    }
    
    BinData.prototype.toPYUUID = function () {
        var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs
        var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
        return 'PYUUID("' + uuid + '")';
    }
    
    
    BinData.prototype.toHexUUID = function () {
        var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs
        var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
        return 'HexData(' + this.subtype() + ', "' + uuid + '")';
    }
    View Code

    仓储层的调用:

    using KuRuMi.Mio.DoMain.Model.Model;
    using KuRuMi.Mio.DoMain.Model.Repositories;
    using KuRuMi.Mio.DoMain.Repository.EFRepository;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace KuRuMi.Mio.DoMain.Repository.ModelRepository
    {
        public class UserRepositoryImpl : RepositoryImpl<User>, IUserRepository
        {
            public KurumiMioDbContext context => lazy.Context as KurumiMioDbContext;
            /// <summary>
            /// 登录
            /// </summary>
            /// <param name="Email"></param>
            /// <param name="PassWord"></param>
            /// <returns></returns>
            public string CheckUser(string Email, string PassWord)
            {
                try
                {
                    User entity = null;
                    //MongoDb取
                    entity = Mongo.FindSingleIndex<User>(a => a.Email == Email);
                    if (entity == null)
                    {
                        //redis取
                        entity = Redis.RedisString.Value.StringGet<User>(Email);
                    }
                    if (entity == null)
                    {
                        //数据库取
                        string sql = "select Id,UserName,Password,email from [User] as a where a.Email ='{0}' and  a.PassWord ='{1}'";
                        string select = string.Format(sql, Email, PassWord);
                        entity = context.user.SqlQuery(select).FirstOrDefault();
                    }
                    return entity.UserName;
                }
                catch (Exception e)
                {
                    return "";
                }
            }
    
            /// <summary>
            /// 保存
            /// </summary>
            /// <param name="aggregateRoot"></param>
            public async override void Add(User aggregateRoot)
            {
                base.Add(aggregateRoot);
                await Redis.RedisString.Value.StringSetAsync(aggregateRoot.Email, aggregateRoot);//保存一份到redis
                Mongo.AddSignleObjectAsync(aggregateRoot);//保存一份到mongoDb
            }
    
            /// <summary>
            /// 注册
            /// </summary>
            /// <param name="info"></param>
            /// <returns></returns>
            public User GetAll(User info)
            {
                string sql = "select Id,UserName,Password,email from [User] as a where a.UserName ='{0}' and email ='{1}'";
                string select = string.Format(sql, info.UserName, info.Email);
                return context.user.SqlQuery(select).FirstOrDefault();
            }
        }
    }
    View Code

     图1:

    图2:

    图3:

    图4:

    图5:

     

    图6:

    图7:

    图8:

    图9:

  • 相关阅读:
    debug error 错误日志的调试模式
    fork(2)
    Fundamental theorem of arithmetic 为什么1不是质数
    Compile-time Dependency Injection With Go Cloud's Wire 编译时依赖注入 运行时依赖注入
    LevelDB
    MySQL Bugs: #34354: Feature request: EXPLAIN ALTER TABLE https://bugs.mysql.com/bug.php?id=34354
    explain 分析 聚合统计语句的性能
    (原创)《Android编程权威指南》学习笔记01-- Android应用初体验--005
    (原创)《Android编程权威指南》学习笔记01-- Android应用初体验--004
    (原创)《Android编程权威指南》学习笔记01-- Android应用初体验--003
  • 原文地址:https://www.cnblogs.com/edna-lzh/p/6972661.html
Copyright © 2011-2022 走看看