分布式服务器框架之Servers.Core库中实现 MongoEntityBase 实现阻塞 异步对MongoDB的增删改查

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: YFMongoDBModelBase类是个模板类,对模板参数进行了约束YFMongoEntityBase,必须要继承YFMongoEntityBase

YFMongoDBModelBase类是个模板类,对模板参数进行了约束YFMongoEntityBase,必须要继承YFMongoEntityBase


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Driver;
namespace Servers.Core
{
    // MongoDBModel 基类
    //要继承YFMongoEntityBase
    public abstract class YFMongoDBModelBase<T>
        where T : YFMongoEntityBase, new()
    {
        #region 子类需要实现的属性
        //MongoDB的客户端类(MongoDB是服务器,链接MongoDb的服务器就变成了客户端了)
        protected abstract MongoClient Client
        {
            get;
        }
        //数据库名称
        protected abstract string DatabaseName
        {
            get;
        }
        //集合名称(对应的是Mysql或者是SqlServer中的Table)
        protected abstract string CollectionName
        {
            get;
        }
        //是否记录错误日志(这个一般都要开启的吧?)
        protected virtual bool CanLogError
        {
            get { return false; }
        }
        #endregion
        #region 获取文档集合 GetCollection
        //写了类型之后是会把Mongo中的二进制数据实例化成这个entity类??
        private IMongoCollection<T> m_Collection = null;
        //获取文档集合(get某个类型的Collection,相当于获取某个类型的Table,不过怎么感觉那么奇怪)
        public IMongoCollection<T> GetCollection()
        {
            try
            {
                if (null == m_Collection)
                {
                    IMongoDatabase database = Client.GetDatabase(DatabaseName);
                    m_Collection = database.GetCollection<T>(CollectionName);
                }
                return m_Collection;
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:log类还没写,后面有了log类之后这里的log打印要补上
                }
                else
                {
                    throw e;
                }
                return null;
            }
        }
        #endregion
        #region GetEntity 根据编号查询实体
        //根据编号查询实体
        public T GetEntity(long YFId)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                FilterDefinition<T> filter = Builders<T>.Filter.Eq("YFId", YFId);
                return collection.Find(filter).FirstOrDefault();
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:记录错误日志
                }
                else
                {
                    throw e;
                }
                return null;
            }
        }
        //异步根据编号查询实体
        public async Task<T> GetEntityAsync(long YFId)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                FilterDefinition<T> filter = Builders<T>.Filter.Eq("YFId", YFId);
                return await collection.Find(filter).FirstOrDefaultAsync();
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:记录错误日志
                }
                else
                {
                    throw e;
                }
                return null;
            }
        }
        //根据条件查询实体
        public T GetEntity(FilterDefinition<T> filter)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                return collection.Find(filter).FirstOrDefault();
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else
                {
                    throw e;
                }
                return null;
            }
        }
        //异步根据条件查询实体
        public async Task<T> GetEntityAsync(FilterDefinition<T> filter)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                return await collection.Find(filter).FirstOrDefaultAsync();
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else
                {
                    throw e;
                }
                return null;
            }
        }
        #endregion
        #region 查询数量
        //查询数量(传进去一个规则策略,寻找符合规则的集合数量)
        public long GetCount(FilterDefinition<T> filter)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                return collection.CountDocuments(filter);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else 
                {
                    throw e;
                }
                return 0;
            }
        }
        //异步查询数量
        public async Task<long> GetCountAsync(FilterDefinition<T> filter)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                return await collection.CountDocumentsAsync(filter);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else
                {
                    throw e;
                }
                return 0;
            }
        }
        #endregion
        #region 根据条件查询数据集合
        /// <summary>
        /// 异步根据条件查询数据集合
        /// </summary>
        /// <param name="filter">过滤条件</param>
        /// <param name="sort">排序</param>
        /// <param name="skip">跳过</param>
        /// <param name="limit">限制数量</param>
        public List<T> GetList(FilterDefinition<T> filter, out long count, string[] field = null, SortDefinition<T> sort = null)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                count = collection.CountDocuments(filter);
                //不指定查询字段???
                if (field == null || field.Length == 0)
                {
                    if (sort == null) 
                        return collection.Find(filter).ToList();
                    //如果有排序规则,进行排序
                    return collection.Find(filter).Sort(sort).ToList();
                }
                //这个的直接翻译叫投影,可以理解成一种投影关系,包含这个名字的(但是不知道include是查找所有的json字符串吗?)
                List<ProjectionDefinition<T>> fieldList = new List<ProjectionDefinition<T>>();
                for (int i=0;i< fieldList.Count;++i)
                {
                    fieldList.Add(Builders<T>.Projection.Include(fieldList[i].ToString()));
                }
                ProjectionDefinition<T> projection = Builders<T>.Projection.Combine(fieldList);
                //可空类型,不为空就调用Clear
                fieldList?.Clear();
                //没排序规则,就不排序
                if (sort == null)
                    return collection.Find(filter).Project<T>(projection).ToList();
                //三重规则??mmp
                return collection.Find(filter).Sort(sort).Project<T>(projection).ToList();
            }
            catch(Exception e) 
            {
                if (CanLogError)
                {
                }
                else 
                {
                    throw e;
                }
                count = 0;
                return null;
            }
        }
        /// <summary>
        /// 异步根据条件查询数据集合
        /// </summary>
        /// <param name="filter">过滤条件</param>
        /// <param name="sort">排序</param>
        /// <param name="skip">跳过</param>
        /// <param name="limit">限制数量</param>
        public async Task<List<T>> GetListAsync(FilterDefinition<T> filter,string[] field = null, SortDefinition<T> sort = null)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                //count = collection.CountDocuments(filter);
                if (field == null || field.Length == 0)
                {
                    if (sort == null)
                        return await collection.Find(filter).ToListAsync();
                    //如果有排序规则,进行排序
                    return await collection.Find(filter).Sort(sort).ToListAsync();
                }
                //这个的直接翻译叫投影,可以理解成一种投影关系,包含这个名字的(但是不知道include是查找所有的json字符串吗?)
                List<ProjectionDefinition<T>> fieldList = new List<ProjectionDefinition<T>>();
                for (int i = 0; i < fieldList.Count; ++i)
                {
                    fieldList.Add(Builders<T>.Projection.Include(fieldList[i].ToString()));
                }
                ProjectionDefinition<T> projection = Builders<T>.Projection.Combine(fieldList);
                //可空类型,不为空就调用Clear
                fieldList?.Clear();
                //没排序规则,就不排序
                if (sort == null)
                    return await collection.Find(filter).Project<T>(projection).ToListAsync();
                return await collection.Find(filter).Sort(sort).Project<T>(projection).ToListAsync();
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                }
                else
                {
                    throw e;
                }
                //count = 0;
                return null;
            }
        }
        /// <summary>
        /// 查询分页集合
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <param name="pageSize">每页数量</param>
        /// <param name="pageIndex">当前页</param>
        /// <param name="count">总数量</param>
        /// <param name="field">字段</param>
        /// <param name="sort">排序</param>
        public List<T> GetListByPage(FilterDefinition<T>filter,int pageSize,int pageIndex,out long count,string[] field=null,SortDefinition<T>sort=null)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                count = collection.CountDocuments(filter);
                //不查询指定字段
                if (field == null || field.Length == 0)
                {
                    if (sort == null)
                        return collection.Find(filter).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
                    //如果有排序规则进行排序
                    collection.Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
                }
                //制定查询字段
                List<ProjectionDefinition<T>> fieldList = new List<ProjectionDefinition<T>>();
                for (int i = 0; i < field.Length; ++i)
                {
                    fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));    
                }
                ProjectionDefinition<T> projection  =Builders<T>.Projection.Combine(fieldList);
                fieldList?.Clear();
                //不排序
                if(sort==null)
                    return collection.Find(filter).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
                //先投影再排序?这样投影出来的不久不会参与排序了嘛?
                return collection.Find(filter).Sort(sort).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else
                {
                    throw e;
                }
                count = 0;
                return null;
            }
        }
        /// <summary>
        /// 异步查询分页集合
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <param name="pageSize">每页数量</param>
        /// <param name="pageIndex">当前页</param>
        /// <param name="field">字段</param>
        /// <param name="sort">排序</param>
        public async Task<List<T>> GetListByPageAsync(FilterDefinition<T> filter, int pageSize, int pageIndex, string[] field = null, SortDefinition<T> sort = null)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                //count = collection.CountDocuments(filter);
                //不查询指定字段
                if (field == null || field.Length == 0)
                {
                    if (sort == null)
                        return await collection.Find(filter).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
                    //如果有排序规则进行排序
                    collection.Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
                }
                //制定查询字段
                List<ProjectionDefinition<T>> fieldList = new List<ProjectionDefinition<T>>();
                for (int i = 0; i < field.Length; ++i)
                {
                    fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
                }
                ProjectionDefinition<T> projection = Builders<T>.Projection.Combine(fieldList);
                fieldList?.Clear();
                //不排序
                if (sort == null)
                    return await collection.Find(filter).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
                return await collection.Find(filter).Sort(sort).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else
                {
                    throw e;
                }
                //count = 0;
                return null;
            }
        }
        #endregion
        #region Add添加实体
        //添加实体
        public void Add(T entity)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                collection.InsertOne(entity);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                }
                else
                {
                    throw e;
                }
            }
        }
        //异步添加实体
        public async Task AddAsync(T entity)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                await collection.InsertOneAsync(entity);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                }
                else
                {
                    throw e;
                }
            }
        }
        #endregion
        #region AddMany 添加多个实体
        //添加多个实体
        public void AddMany(List<T> lst)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                collection.InsertMany(lst);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:   
                }
                else
                {
                    throw e;
                }
            }
        }
        //异步添加多个实体
        public async Task AddManyAsync(List<T> lst)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                await collection.InsertManyAsync(lst);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:   
                }
                else
                {
                    throw e;
                }
            }
        }
        #endregion
        #region Update 修改实体
        //修改实体
        public void Update(T entity)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                FilterDefinition<T> filter = Builders<T>.Filter.Eq("YFId", entity.YFId);
                collection.FindOneAndReplace(filter,entity);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else
                {
                    throw e;
                }
            }
        }
        //异步修改实体
        public async Task UpdateAsync(T entity)
        {
            try
            {
                IMongoCollection<T> collection = GetCollection();
                FilterDefinition<T> filter = Builders<T>.Filter.Eq("YFId", entity.YFId);
                await collection.FindOneAndReplaceAsync(filter, entity);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else
                {
                    throw e;
                }
            }
        }
        #endregion
        #region 删除实体
        //删除实体
        public void Delete(long YFId)
        {
            try
            {
                T entity = GetEntity(YFId);
                if (null != entity)
                {
                    entity.Status = DataStatus.Delete;
                    Update(entity);
                }
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else
                {
                    throw e;
                }
            }
        }
        //异步删除实体
        public async Task DeleteAsync(long YFId)
        {
            try
            {
                T entity = await GetEntityAsync(YFId);
                if (null != entity)
                {
                    entity.Status = DataStatus.Delete;
                    await UpdateAsync(entity);
                }
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO:
                }
                else
                {
                    throw e;
                }
            }
        }
        #endregion
        #region 删除所有文档
        public void DeletaAll()
        {
            try
            {
                //删库跑路了??drop这个table
                IMongoDatabase database = Client.GetDatabase(DatabaseName);
                database.DropCollection(CollectionName);
                //drop了为啥还要再create一下?为了完全覆盖内存吗???
                database.CreateCollection(CollectionName);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO
                }
                else 
                {
                    throw e;
                }
            }
        }
        public async Task DeletaAllAsync()
        {
            try
            {
                IMongoDatabase database = Client.GetDatabase(DatabaseName);
                await database.DropCollectionAsync(CollectionName);
                await database.CreateCollectionAsync(CollectionName);
            }
            catch (Exception e)
            {
                if (CanLogError)
                {
                    //TODO
                }
                else
                {
                    throw e;
                }
            }
        }
        #endregion
    }
}
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
1月前
|
JSON API 数据格式
基于服务器响应的实时天气数据进行JSON解析的详细代码及其框架
【8月更文挑战第25天】这段资料介绍了一个使用Python从服务器获取实时天气数据并解析JSON格式数据的基本框架。主要分为三个部分:一是安装必要的`requests`库以发起HTTP请求获取数据,同时利用Python内置的`json`库处理JSON数据;二是提供了具体的代码实现,包括获取天气数据的`get_weather_data`函数和解析数据的`parse_weather_data`函数;三是对代码逻辑进行了详细说明,包括如何通过API获取数据以及如何解析这些数据来获取温度和天气描述等信息。用户需要根据实际使用的天气API调整代码中的API地址、参数和字段名称。
|
1月前
|
缓存 监控 中间件
构建高效的Go语言Web服务器:基于Fiber框架的性能优化实践
在追求极致性能的Web开发领域,Go语言(Golang)凭借其高效的并发处理能力、垃圾回收机制及简洁的语法赢得了广泛的青睐。本文不同于传统的性能优化教程,将深入剖析如何在Go语言环境下,利用Fiber这一高性能Web框架,通过精细化配置、并发策略调整及代码层面的微优化,构建出既快速又稳定的Web服务器。通过实际案例与性能测试数据对比,揭示一系列非直觉但极为有效的优化技巧,助力开发者在快节奏的互联网环境中抢占先机。
|
2月前
|
存储 NoSQL 关系型数据库
MongoDB的配置服务器和复制机制
【7月更文挑战第2天】MongoDB配置服务器存储分片和权限元数据,支持在主节点故障时保持读服务。关键组件,性能影响显著。复制集包含Primary和Secondary,通过oplog实现数据同步,类似MySQL binlog。oplog的幂等性可能导致大量set操作,且大小受限,可能导致从节点需全量同步。读写分离提升效率,主从切换确保高可用。
33 0
|
4月前
|
JSON 中间件 数据格式
在服务器框架中处理 POST 请求
在服务器框架中处理 POST 请求
在自定义服务器框架中处理 GET 请求
在自定义服务器框架中处理 GET 请求
|
4月前
|
JSON 中间件 数据格式
在自定义服务器框架中处理 POST 请求
在自定义服务器框架中处理 POST 请求
|
3月前
|
缓存 JavaScript 前端开发
Nuxt.js实战:Vue.js的服务器端渲染框架
Nuxt.js提供了开发、构建和部署的完整工作流。使用nuxt命令启动开发服务器,nuxt build进行生产构建,nuxt start启动生产服务器
71 0
|
18天前
|
Cloud Native Java 编译器
将基于x86架构平台的应用迁移到阿里云倚天实例云服务器参考
随着云计算技术的不断发展,云服务商们不断推出高性能、高可用的云服务器实例,以满足企业日益增长的计算需求。阿里云推出的倚天实例,凭借其基于ARM架构的倚天710处理器,提供了卓越的计算能力和能效比,特别适用于云原生、高性能计算等场景。然而,有的用户需要将传统基于x86平台的应用迁移到倚天实例上,本文将介绍如何将基于x86架构平台的应用迁移到阿里云倚天实例的服务器上,帮助开发者和企业用户顺利完成迁移工作,享受更高效、更经济的云服务。
将基于x86架构平台的应用迁移到阿里云倚天实例云服务器参考
|
16天前
|
编解码 前端开发 安全
通过阿里云的活动购买云服务器时如何选择实例、带宽、云盘
在我们选购阿里云服务器的过程中,不管是新用户还是老用户通常都是通过阿里云的活动去买了,一是价格更加实惠,二是活动中的云服务器配置比较丰富,足可以满足大部分用户的需求,但是面对琳琅满目的云服务器实例、带宽和云盘选项,如何选择更适合自己,成为许多用户比较关注的问题。本文将介绍如何在阿里云的活动中选择合适的云服务器实例、带宽和云盘,以供参考和选择。
通过阿里云的活动购买云服务器时如何选择实例、带宽、云盘
|
14天前
|
弹性计算 运维 安全
阿里云轻量应用服务器和经济型e实例区别及选择参考
目前在阿里云的活动中,轻量应用服务器2核2G3M带宽价格为82元1年,2核2G3M带宽的经济型e实例云服务器价格99元1年,对于云服务器配置和性能要求不是很高的阿里云用户来说,这两款服务器配置和价格都差不多,阿里云轻量应用服务器和ECS云服务器让用户二选一,很多用户不清楚如何选择,本文来说说轻量应用服务器和经济型e实例的区别及选择参考。
阿里云轻量应用服务器和经济型e实例区别及选择参考