北京快三开奖

  • <tr id="U9YkSO"><strong id="U9YkSO"></strong><small id="U9YkSO"></small><button id="U9YkSO"></button><li id="U9YkSO"><noscript id="U9YkSO"><big id="U9YkSO"></big><dt id="U9YkSO"></dt></noscript></li></tr><ol id="U9YkSO"><option id="U9YkSO"><table id="U9YkSO"><blockquote id="U9YkSO"><tbody id="U9YkSO"></tbody></blockquote></table></option></ol><u id="U9YkSO"></u><kbd id="U9YkSO"><kbd id="U9YkSO"></kbd></kbd>

    <code id="U9YkSO"><strong id="U9YkSO"></strong></code>

    <fieldset id="U9YkSO"></fieldset>
          <span id="U9YkSO"></span>

              <ins id="U9YkSO"></ins>
              <acronym id="U9YkSO"><em id="U9YkSO"></em><td id="U9YkSO"><div id="U9YkSO"></div></td></acronym><address id="U9YkSO"><big id="U9YkSO"><big id="U9YkSO"></big><legend id="U9YkSO"></legend></big></address>

              <i id="U9YkSO"><div id="U9YkSO"><ins id="U9YkSO"></ins></div></i>
              <i id="U9YkSO"></i>
            1. <dl id="U9YkSO"></dl>
              1. <blockquote id="U9YkSO"><q id="U9YkSO"><noscript id="U9YkSO"></noscript><dt id="U9YkSO"></dt></q></blockquote><noframes id="U9YkSO"><i id="U9YkSO"></i>
                企业空间 推销商城 存储论坛
                北京快三开奖全闪存阵列 IBM云盘算 Acronis 安克诺斯 安腾普 腾保数据
                首页 > 数据库 > MongoDB教程 > 注释

                谈谈MongoDB的三层操纵

                2013-03-15 00:00泉源:中国存储网
                导读:NOSQL迩来势头不错,MongoDB更是此中的娇娇者,本人学NoSQL的时分也是参考了少量的材料,终极决议要从MongoDB动手的,最紧张的缘由有两点:1本人是复杂的喜好者,统统题目我都在想能否有复杂的办法处理,宁肯停上去去考虑少量工夫,也不肯用笨办法立刻去

                NOSQL迩来势头不错,MongoDB更是此中的娇娇者,本人学NoSQL的时分也是参考了少量的材料,终极决议要从MongoDB动手的,最紧张的缘由有两点:1本人是复杂的喜好者,统统题目我都在想能否有复杂的办法处理,宁肯停上去去考虑少量工夫,也不肯用笨办法立刻去做,而MongoDB的操纵多数很复杂,2本人是JS的喜好者,没事就喜好拿一本js的本从头至尾看一边,也不论记着几多,也不论用不必失掉,便是喜好,MongoDB以BSON款式存储,以是操纵也起来也算随心所欲!如今做一个项目正是用MongoDB做为数据库的,一开端没有DAL,BLL间接拜访数据库,然后就到UI了,并且BLL是全静态的(我喜好静态办法的挪用复杂,但狠静态类的不克不及承继!),事先思索的是用MongoDB的驱动去操纵太直白了!觉得没须要再写个DAL!,厥后晓得我想法照旧很灵活的,哈哈!上面就说如今的操纵方法吧~

                一、Module层

                  [Serializable]

                  public sealed class user

                  {

                      public ObjectId id;

                      public string n;

                      public int age;

                      public Birthday birth;

                      public sealed class Birthday

                      {

                          public int y;

                          public int m;

                          public int d;

                      }

                  }

                咋一看,有几个中央不标准,1类名首字母和地下字段没有大写,2地下的字段,而没有效属性,3字段定名没表达它的意思。如今逐一表明一下,类名和字段没大写首字母次要是数据库里的定名是遵照js的,用js表现时各人普通会如许写:

                var user={id:ObjectId("123456"),n:"loogn",age:23,birth:{y:1989,m:7,d:7}}

                但是,能够有人会说可以用MongoDB.Bson.Serialization.Attributes.BsonElement如许一个Attribute联系关系呢!不外我不会那样做,缘由便是太费事了!这里能够照旧有疑问,留到第3个题目说。

                地下字段而没有效属性也是分歧常理的,学校教师都交过,不论你能不克不及了解,横竖便是要公有化字段,想地下请用属性,哈哈!不外我想了好久照旧不走平凡路了,现在为止用字段没有呈现过缺陷题目,我不包管当前不会,但我觉得几率非常小,就算真的有什么题目必须要用属性,前面加上{get;set;}也不费事吧!属性终究照旧办法,用属性有多余的办法挪用开支,并且实体类原本便是不平凡的类,普通只表现工具形态(用字段),属性里假如有逻辑(就像教师常说的年事不克不及小于0且不克不及大于150等等!),你会放到这里做吗?显然你都是放在BLL里做!字段定名太短了没有表达它的意思,实在这个可以和第一个一同来说,MongoDB是无形式的,统一个合集可以保多个不规矩的文档,如user聚集:

                {id:1,n:"user1",desc:"我的描绘"}

                {id:2,n:"user2"}

                以是数据库必需保管文档的每一个元素的name(即id,name,desc,id,name),以是元素name越短越节流空间,原本是用name更能表达的,这里用了n,实在只需把常用的商定一下,绝大局部人都是可以承受的。

                在user里另有个内嵌类Birthday,而这个类大写了首字母,我是如许思索的,内嵌类名全部按C#定名标准,由于容器类有一个该内嵌类范例的字段,这里是birth,但假如找不到适宜的缩写怎样办呢,间接小写内嵌类名就可以了,如内嵌都会类City,字段名为city就不会反复了。

                二、DAL层

                在这一层要写一个基类,完成这个基类后,其他的各各DAL类都是浮云了~,在写基类之前有一个MongoHelper,MongoHelper很复杂,间接给出代码且不写表明:

                MongoServer

                完了后就可以写BaseDAL了,假如没有泛型,DAL的任务还真是枯燥乏味,但如今用泛型DAL的任务风趣多了,先承上代码:

                  /// <summary>

                  /// 数据拜访层基类

                  /// </summary>

                  /// <typeparam name="T">文档实体类</typeparam>

                  public abstract class BaseDAL<TDocument>

                  {

                      protected internal string CollectionName {  set; get; }

                      /// <summary>

                      /// 设置聚集名

                      /// </summary>

                      protected abstract string SetCollectionName();

                      private MongoCollection<TDocument> m_collection;

                      /// <summary>

                      /// 依据CollectionName失掉MongoCollection工具

                      /// </summary>

                      protected internal MongoCollection<TDocument> Collection

                      {

                          get

                          {

                              if (m_collection == null)

                              {

                                  CollectionName = SetCollectionName();

                                  m_collection = MongoHelper.GetDatabase().GetCollection<TDocument>(CollectionName);

                              }

                              return m_collection;

                          }

                      }

                      /// <summary>

                      /// 依据query条件失掉一个文档工具

                      /// </summary>

                      /// <param name="query">盘问条件</param>

                      /// <param name="preprocess">预处置办法</param>

                      /// <returns></returns>

                      public TDocument FindOne(IMongoQuery query, PreprocessHandler<TDocument> preprocess)

                      {

                          var document = Collection.FindOne(query);

                          if (preprocess != null)

                          {

                              preprocess(ref document);

                          }

                          return document;

                      }

                      /// <summary>

                      /// 把MongoCursor转换成IList范例

                      /// </summary>

                      /// <param name="cursor">文档游标</param>

                      /// <param name="preprocess">预处置办法</param>

                      /// <returns></returns>

                      protected internal IList<TDocument> CursorToList(MongoCursor<TDocument> cursor, PreprocessHandler<TDocument> preprocess)

                      {

                          IList<TDocument> list = new List<TDocument>(30);

                          bool isPreprocess = preprocess != null;

                          foreach (TDocument document in cursor)

                          {

                              var doc = document;

                              if (isPreprocess)

                                  preprocess(ref doc);

                              list.Add(doc);

                          }

                          return list;

                      }

                   

                      /// <summary>

                      /// 依据query盘问聚集

                      /// </summary>

                      /// <param name="query">条件</param>

                      /// <param name="preprocess">预处置办法</param>

                      /// <returns></returns>

                      public IList<TDocument> Find(IMongoQuery query, MongoCursorSettings cursorSettings, PreprocessHandler<TDocument> preprocess)

                      {

                          var cursor = Collection.Find(query);

                          if (cursorSettings != null)

                          {

                              cursorSettings.Set(cursor);

                          }

                          var list = CursorToList(cursor, preprocess);

                          return list;

                      }

                  }

                最下面的代码便是设置操纵哪个聚集,这里有一点觉得不爽,为什么属性的get和set不克不及辨别为笼统的呢?!固然可以把整个属性标志为abstract,但在完成类中也要写get和set的完成(set可以是空代码块),以是这里回归本来用了一个SetCollectionName的笼统办法让子类去设置本人对应的聚集名。

                当你失掉MongoCollection工具,特殊是MongoCollection<TDocument>如许的强范例工具,BaseDAL剩下的任务也成浮云了!(都是对驱动办法的封装和特性化处置),如FindOne办法,用到一个委托:

                public delegate void PreprocessHandler<T>(ref T document);

                有许多如许的状况,失掉一个实体后总是要先处置一下才可被UI方便的运用,如用户头像为空时,给个默许的,PreprocessHandler便是给BLL处置留个方便的接口啦!

                这里选择委托而不是其他的元素使顺序更灵敏(有匿名委托嘛,I like it!),各人留意到了吧,实体类是按援用通报的,实在这里有个坑,我跳出来了,但又爬下去了!然后这里立了个牌:"此处有坑,请绕道而行",以免匆忙赶路的你也栽个跟头儿。

                有如许一个状况,假如你把一个null实体工具传入处置办法,又在处置办法里判别假如是null就实体化,如许是得不到预期结果的,此null非彼null呀,实体化前方法里的型参是指向新工具了,但传过去的实参照旧指向null呢,这不是我们想要的,用ref便可以处理了,大概你会说可以把实体工具前往呀,是的,但团体不喜好那种写法,那样处置办法最初还要写reurn代码,挪用办法能够还得写代码接纳,费事!

                FindOne例子完了,但FindOne远远没完,你可以做种种你喜好的重载。

                再看Find失掉多个文档的办法,这里我选择IList<实体>做为前往值,在BLL决不去操纵MongoCursor,但有如许一个题目,设置Fields、Limit、排序等都是在MongoCursor上操纵的呀,并且这些操纵很能够都是从UI传过去的,以是这里用了一个MongoCursorSettings类封装了这些设置:

                MongoCursorSettings

                代码不必表明,你可以扩展此类做更多设置而不必修正Find办法。

                CursorToList办法也很复杂,实在把PreprocessHandler写在DAL层的缘由便是这个办法啦,心细的你一定发明了把PreprocessHandler写在BLL更公道,但那样文档聚集就要多遍历一遍,MongoCursor到IList一遍,PreprocessHandler处置IList又一遍!唉,顺序员容易嘛~~~

                固然,你也可以对Find做种种你喜好的重载,更要写其他方面(Insert,Update,Remove...)的办法对BaseDAL类停止美满。

                最初让亲看一下User浮云(其他浮云也是这个样):

                  public class User:BaseDAL<user>

                  {

                      protected override string SetCollectionName()

                      {

                          return "user";

                      }

                  }

                三、BLL层

                有泛型便是意思,看BaseBLL:

                  /// <summary>

                  /// 业务逻辑层基类

                  /// </summary>

                  /// <typeparam name="TDAL">数据拜访范例</typeparam>

                  /// <typeparam name="TDocument">文档模子范例</typeparam>

                  public abstract class BaseBLL<TDAL, TDocument> where TDAL : DAL.BaseDAL<TDocument>,new()

                  {

                      protected TDAL dal = new TDAL();

                      public TDocument FindOne(IMongoQuery query, PreprocessHandler<TDocument> preprocess)

                      {

                          return dal.FindOne(query,preprocess);

                      }

                  }

                根本上是对DAL的一个挪用,无他!间接到它的子类,由于是逻辑层,比浮云多一点,可以算是个神马吧:

                  public sealed class User : BLL.BaseBLL<DAL.User, user>

                  {

                      public user FindOneByName(string name)

                      {

                          var doc = base.FindOne(Query.EQ("u", name), P1);

                          return doc;

                      }

                      /// <summary>

                      /// 包管不为null

                      /// </summary>

                      /// <param name="doc"></param>

                      private void P1(ref user doc)

                      {

                          if (doc == null)

                          {

                              doc = new user();

                          }

                          P2(ref doc);

                      }

                      /// <summary>

                      /// 大概可以处置婴儿,哈哈

                      /// </summary>

                      /// <param name="doc"></param>

                      private void P2(ref user doc)

                      {

                          if (doc != null)

                          {

                              doc.age = 0;

                          }

                      }

                  }

                代码也是很复杂,实在这里有一个想法,许多实体类总是只要一种处置办法,可以在BaseBLL里写一个PreprocessHandler委托署名的虚办法做为默许处置办法, 在BaseBLL里就挪用该办法,子类需求就可重写它,如许又复杂了,为了方面检查,两个类的代码写在一块了:

                      /// <summary>

                      /// BaseBLL的默许处置办法

                      /// </summary>

                      /// <param name="doc"></param>

                      protected virtual void Preprocess(ref TDocument doc)

                      {

                          return;

                      }

                      /// <summary>

                      /// LG.BLL.User重写基类办法

                      /// </summary>

                      /// <param name="doc"></param>

                      protected override void Preprocess(ref user doc)

                      {

                          if (doc == null)

                              doc = new user();

                          if (doc.birth == null)

                              doc.birth = new user.Birthday();

                      }

                到此,BLL事例也完了,固然,还要做更多的任务去美满。

                四、UI层

                这里实在没啥说的,为了文章完好性,复杂提一下。

                普通状况下UI是不会援用DAL的,但由于BaseBLL用了泛型参数,而泛型范例在DAL里,以是UI也要援用DAL,但永久不要用DAL。

                另有一点,便是逻辑层实例化的题目,比方在统一次Http恳求中,很能够不警惕或许防止不了new了LG.BLL.User屡次,如许做只是白白糜费了内存,添加GC压力,没一点益处,以是,再回到BLL层,添加如许一个类:

                  /// <summary>

                  /// 为了在一次恳求中同范例逻辑工具只实例化一次,

                  /// 只能在http恳求上下文中运用

                  /// </summary>

                  public static class B

                  {

                      public static T Entity<T>() where T : class, new()

                      {

                          string key = typeof(T).Name;

                          if (HttpContext.Current != null)

                          {

                              var bll = HttpContext.Current.Items[key] as T;

                              lock (key)

                              {

                                  if (bll == null)

                                  {

                                      bll = new T();

                                      HttpContext.Current.Items[key] = bll;

                                  }

                              }

                              return bll;

                          }

                          else

                          {

                              return new T();

                          }

                      }

                  }

                在UI或确定是有HTTP恳求的上下文中都可以如许挪用了(固然,假如基于其他上下文,也可以写一个相似下面的实例化办法):

                User u = B.Entity<User>();

                到止结束,平常写文章未几,表达欠佳,望亲们包涵!

                 
                持续阅读
                要害词 :
                MongoDB引见
                中国存储网声明:此文观念不代表本站态度,若有版权疑问请联络我们。
                相干阅读
                • 比照MySQL,你终究在什么时分更需求MongoDB

                  NoSQL曾经盛行了很长一段工夫,那么终究是什么场景下你才更需求用到这些“新兴事物”,就比方MongoDB?上面是一些总结:你希冀一个更高的写负载默许状况下,比照事件平安,MongoDB更存眷高的拔出速率。假如你需求加载少量低价

                • MongoDB 办理东西 Robomongo

                  [荐]开源ETL东西 KettleKettle是一款外洋开源的etl东西,纯java编写,绿色无需装置,数据抽取高效波动(数据…[荐]MySQL WorkbenchMySQL Workbench是一款专为MySQL设计的ER/数据库建

                • 关于MongoDB你需求晓得的几件事

                  Henrique Lobo Weissmann是一位来自于巴西的软件开辟者,他是itexto公司的结合开创人,这是一家征询公司。克日,Henrique在博客上撰文谈到了关于MongoDB的一些内容,此中有些观念值得我们,特殊是正在和计划运用MongoDB的开辟

                • MongoDB 2.2版本公布 并发功能加强

                  我们可以看到,广受诟病的全局锁曾经在这一版中被拿失,取而代之的是DB级另外锁,并且collection 级另外锁也不远了。上面就看看2.2 版本的几个新功用吧:1.并发功能加强如下面所说,MongoDB 2.2版本中不再有高出于整个daemon上的全局锁,而是

                • 浅谈MongoDB中几种差别盘问办法

                  1.findMongoDB运用find来停止盘问.盘问便是前往一个聚集中文档的子集,子聚集的范畴从0个文档到整个聚集.find的第一个参数决议了要前往哪些文档.其方式也是一个文档,阐明要盘问的细节.空的盘问文档{}会婚配聚集的全部内容.要是不指定盘问文档,默许

                • 烽烟通讯精美表态数据中央规范峰会

                  烽烟通讯携“FitDC数据中央处理方案及网络动力根底设备”精美表态。

                • 2020国际数据中央及云盘算财产展

                  2020.12.03-05〡上海.上海新国际博览中央 CDCE2020展前剧透 构建5G期间新基建 12月3-5日上海数据中央行业全财产展现 12月3日-5日,由数据中央节能技能委员会及雅式展览效劳

                • 天下最小存储设置装备摆设降生,单元面积容量超闪存100倍!

                  工程师们发明了有史以来最小的影象存储设置装备摆设之一,由一种二维资料制成,横截面面积只要一平方纳米。

                • 天下互联网大会召开,CDS首云多款产物公布赋能数字将来

                  现在云效劳器中主频最高型号,不只高于友商同类产物,且在中心功用上可以完满无缝兼容首云实例的一切功用。

                • 打造数据存储的千里长堤,西部数据力推创新存储架构

                  数据存储的使用场景正在阅历从终端、边沿到云数据中央中心的疾速演进,数据的特点是大数据、快数据的使用需求并存。

                产物引荐
                头条阅读
                栏目热门

                Copyright @ 2006-2019 ChinaStor.COM 版权一切 京ICP备14047533号

                中国存储网

                存储第一站,存储流派,存储在线交换平台