第二部分 尝试解决BulkWrite(List<WriteModel<T>>)问题

在上次发表的文章中,得到了一些很好的反馈,真切体会到写博文的好处,有高人指出两大问题,具体可以看看上篇中的评论,下面依然是发表一些个人见解,只做研究,并不保证解决实际问题。

这两大问题终究来说,是发生在BulkWrite(List<WriteModel<T>>)上,针对@ 从来不用 的问题,我试着找出影响的行数据还比对写入操作的数量,如果一致,则提交,如果不一致则回滚。

1.找出影响行数和实际操作数量    BulkWriteResult<T>有很多属性,我用的是ProcessedRequests.Count这个应该是反应的像mssql的影响的行数。而实际操作数量就是writer的个数。

2.备份元数据   每添加一个writer之前在内存中或备份数据库中保存一份元数据,我这里是保存在内存中的,声明了几个不同类型的集合

  1. private List<TAggregate> beforeChange = new List<TAggregate>();//记录更新前的数据
  2. private List<Guid> beforeAdd = new List<Guid>(); //记录添加前的数据ID
  3. private List<TAggregate> beforeDelete = new List<TAggregate>();//记录数据删除前的数据

  然后在每添加一个writer之前,在对应的修改、添加、删除集合中添加元数据,这里看来必须要有数据库访问的了。没办法

  1. if (IsUseTransaction)
  2. {
  3. try
  4. {
  5. beforeAdd.Add(entity.Id);//记录添加之前的数据的ID
  6. writers.Add(new InsertOneModel<TAggregate>(entity));
  7. isRollback = false;//控制是否回滚
  8. return;
  9. }

   其它操作同理,后面我会把完整的代码贴出来的。先来分析一下。

3.处理提交事务逻辑   利用Collection.BulkWrite(writers)的返回值属性,找出实际影响的数据行数,这里我就按mssql的命名思路来了,同时如果若BulkWriteResult发生异常,我们也执行回滚

  1. #region 事务控制
  2. public void Commit()
  3. {
  4. if (!isRollback && writers.Count > 0)//如果不回滚,并且writers有数据
  5. {
  6. BulkWriteResult<TAggregate> result;
  7. try
  8. {
  9. result = Collection.BulkWrite(writers);
  10. }
  11. catch (Exception)
  12. {
  13. Rollback();//若BulkWriteResult发生异常
  14. throw;
  15. }
  16. if(result.ProcessedRequests.Count!=writers.Count)//检查完成写入的数量,如果有误,回滚
  17. {
  18. Rollback();
  19. }
  20. writers.Clear();//此时说明已成功提交,清空writers数据
  21. return;
  22. }
  23. Rollback();
  24. }

  

 4.回滚操作    回滚嘛,我们就来个反操作,根据不同的类型操作集合,遍历执行反操作写入数据库,至于这部分如果出问题,我现在还没时间搞,以后如果有需要,再改

  1. public void Rollback()
  2. {
  3. writers.Clear();//清空writers
  4. //执行反操作
  5. beforeDelete.ForEach(o =>
  6. {
  7. Collection.InsertOne(o);
  8. });
  9. beforeChange.ForEach(o =>
  10. {
  11. Collection.ReplaceOne(c => c.Id == o.Id, o);
  12. });
  13. beforeAdd.ForEach(o =>
  14. {
  15. Collection.DeleteOne(d => d.Id == o);
  16. });
  17.  
  18. }

5.修整后的Repostory

  1. using EFAndMongoRepostory.Entity;
  2. using MongoDB.Driver;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Linq.Expressions;
  7.  
  8. namespace EFAndMongoRepostory
  9. {
  10. public class MongoRepostory<TAggregate> where TAggregate :AggregateBase
  11. {
  12. #region 初始化及字段属性设置
  13. /// <summary>
  14. /// 获取集合
  15. /// </summary>
  16. protected IMongoCollection<TAggregate> Collection;
  17. /// <summary>
  18. /// 初始化,以类名作为集合名称
  19. /// </summary>
  20. /// <param name="collection"></param>
  21. public MongoRepostory()
  22. {
  23. this.Collection = MongoDbContext.GetMongoCollection<TAggregate>(typeof(TAggregate).Name);
  24. }
  25.  
  26. private List<WriteModel<TAggregate>> writers = new List<WriteModel<TAggregate>>();//写入模型
  27.  
  28. /// <summary>
  29. /// 指示是否起用事务,默认true
  30. /// </summary>
  31. public bool IsUseTransaction { get; set; } = true;
  32.  
  33. private List<TAggregate> beforeChange = new List<TAggregate>();//记录更新前的数据
  34. private List<Guid> beforeAdd = new List<Guid>(); //记录添加前的数据ID
  35. private List<TAggregate> beforeDelete = new List<TAggregate>();//记录数据删除前的数据
  36.  
  37. private bool isRollback = false;//回滚控制
  38. #endregion
  39.  
  40. #region 添加
  41. /// <summary>
  42. /// 添加一条数据
  43. /// </summary>
  44. /// <param name="entity"></param>
  45. public void Add(TAggregate entity)
  46. {
  47. if (entity == null)
  48. return;
  49. if (IsUseTransaction)
  50. {
  51. try
  52. {
  53. beforeAdd.Add(entity.Id);//记录添加之前的数据的ID
  54. writers.Add(new InsertOneModel<TAggregate>(entity));
  55. isRollback = false;//控制是否回滚
  56. return;
  57. }
  58. catch (Exception ex)
  59. {
  60. isRollback = true;
  61. throw new Exception(ex.Message);
  62. }
  63. }
  64. try
  65. {
  66. Collection.InsertOne(entity);
  67. }
  68. catch (Exception ex)
  69. {
  70. throw new Exception(ex.Message);
  71. }
  72. }
  73. /// <summary>
  74. /// 添加数据集合
  75. /// </summary>
  76. /// <param name="entities"></param>
  77. public void Add(IEnumerable<TAggregate> entities)
  78. {
  79. )
  80. return;
  81. if(IsUseTransaction)
  82. {
  83. try
  84. {
  85. entities.ToList().ForEach(o =>
  86. {
  87. beforeAdd.Add(o.Id);
  88. writers.Add(new InsertOneModel<TAggregate>(o));
  89. });
  90. isRollback = false;
  91. return;
  92. }
  93. catch (Exception ex)
  94. {
  95. isRollback = true;
  96. throw new Exception(ex.Message);
  97. }
  98. }
  99. try
  100. {
  101. Collection.InsertMany(entities);
  102. }
  103. catch (Exception ex)
  104. {
  105. throw new Exception(ex.Message);
  106. }
  107. }
  108. #endregion
  109.  
  110. #region 替换
  111. /// <summary>
  112. /// 替换一条过滤的数据(请确保此方法Id属性是不能变)
  113. /// </summary>
  114. /// <param name="filter">过滤条件</param>
  115. /// <param name="enity">目标数据(目标数据的Id值必为源数据的Id)</param>
  116. public void ReplaceOne(Expression<Func<TAggregate, bool>> filter, TAggregate enity)
  117. {
  118. if (enity == null)
  119. return;
  120. if (IsUseTransaction)
  121. {
  122. try
  123. {
  124. //先记录修改之前的数据
  125. beforeChange.Add(Collection.Find(Builders<TAggregate>.Filter.Where(filter)).FirstOrDefault());
  126. writers.Add(new ReplaceOneModel<TAggregate>(Builders<TAggregate>.Filter.Where(filter), enity));
  127. isRollback = false;
  128. return;
  129. }
  130. catch (Exception ex)
  131. {
  132. isRollback = true;
  133. throw new Exception(ex.Message);
  134. }
  135. }
  136.  
  137. try
  138. {
  139. Collection.ReplaceOne(filter, enity);
  140. }
  141. catch (Exception ex)
  142. {
  143. throw new Exception(ex.Message);
  144. }
  145. }
  146. /// <summary>
  147. /// 替换一条数据(请确保此方法Id属性是不能变)
  148. /// </summary>
  149. /// <param name="id">目标id</param>
  150. /// <param name="enity">目标数据(目标数据的Id值必为源数据的Id)</param>
  151. public void ReplaceById(Guid id, TAggregate enity)
  152. {
  153. if (enity == null)
  154. return;
  155. if(enity.Id!=id)
  156. {
  157. isRollback = true;
  158. throw new Exception("the id can not change");
  159. }
  160. if(IsUseTransaction)
  161. {
  162. try
  163. {
  164. beforeChange.Add(Collection.Find(Builders<TAggregate>.Filter.Eq(o => o.Id, id)).FirstOrDefault());
  165. writers.Add(new ReplaceOneModel<TAggregate>(Builders<TAggregate>.Filter.Eq(o=>o.Id, id), enity));
  166. isRollback = false;
  167. return;
  168. }
  169. catch (Exception ex)
  170. {
  171. isRollback = true;
  172. throw new Exception(ex.Message);
  173. }
  174. }
  175. try
  176. {
  177. Collection.ReplaceOne(o => o.Id == id, enity);
  178. }
  179. catch (Exception ex)
  180. {
  181. throw new Exception(ex.Message);
  182. }
  183. }
  184. /// <summary>
  185. /// 查找一条数据并且替换
  186. /// </summary>
  187. /// <param name="id">目标数据的id</param>
  188. /// <param name="enity">更改后的数据</param>
  189. /// <returns>更改前的数据</returns>
  190. public TAggregate FindOneAndReplace(Guid id, TAggregate enity)
  191. {
  192. if (enity == null)
  193. return null;
  194. if (enity.Id != id)
  195. {
  196. throw new Exception("the id can not change");
  197. }
  198.  
  199. return Collection.FindOneAndReplace(o => o.Id == id, enity);
  200. }
  201. /// <summary>
  202. /// 查找一条数据并且替换
  203. /// </summary>
  204. /// <param name="filter">条件</param>
  205. /// <param name="enity">更改后的数据</param>
  206. /// <returns>更改前的数据</returns>
  207. public TAggregate FindOneAndReplace(Expression<Func<TAggregate,bool>>filter, TAggregate enity)
  208. {
  209. if (enity == null)
  210. return null;
  211. return Collection.FindOneAndReplace(filter, enity);
  212. }
  213.  
  214. #endregion
  215.  
  216. #region 移除
  217. /// <summary>
  218. /// 根据过滤删除数据
  219. /// </summary>
  220. /// <param name="filter"></param>
  221. public void Remoe(Expression<Func<TAggregate, bool>> filter)
  222. {
  223. if (IsUseTransaction)
  224. {
  225. try
  226. {
  227. if(Collection.Find(filter).FirstOrDefault()==null)//如果要删除的数据不存在数据库中
  228. {
  229. throw new Exception("要删除的数据不存在数据库中");
  230. }
  231. beforeDelete.Add(Collection.Find(filter).FirstOrDefault());
  232. writers.Add(new DeleteOneModel<TAggregate>(Builders<TAggregate>.Filter.Where(filter)));
  233. isRollback = false;
  234. return;
  235. }
  236. catch (Exception ex)
  237. {
  238. isRollback = true;
  239. throw new Exception(ex.Message);
  240. }
  241. }
  242. try
  243. {
  244. Collection.DeleteMany(filter);
  245. }
  246. catch (Exception ex)
  247. {
  248. throw new Exception(ex.Message);
  249. }
  250. }
  251. public void RemoveById(Guid id)
  252. {
  253. if (IsUseTransaction)
  254. {
  255. try
  256. {
  257. beforeDelete.Add(Collection.Find(Builders<TAggregate>.Filter.Eq(o => o.Id, id)).FirstOrDefault());
  258. writers.Add(new DeleteOneModel<TAggregate>(Builders<TAggregate>.Filter.Eq(o => o.Id, id)));
  259. isRollback = false;
  260. return;
  261. }
  262. catch (Exception ex)
  263. {
  264. isRollback = true;
  265. throw new Exception(ex.Message);
  266. }
  267. }
  268. try
  269. {
  270. Collection.DeleteOne(o => o.Id == id);
  271. }
  272. catch (Exception ex)
  273. {
  274. throw new Exception(ex.Message);
  275. }
  276. }
  277. #endregion
  278.  
  279. #region 更新
  280. /// <summary>
  281. /// 过滤数据,执行更新操作(如不便使用,请用Replace相关的方法代替)
  282. ///
  283. /// 一般用replace来代替这个方法。其实这个功能还算强大的,可以很自由修改多个属性
  284. /// 关健是set参数比较不好配置,并且如果用此方法,调用端必须引用相关的DLL,set举例如下
  285. /// set = Builders<TAggregate>.Update.Update.Set(o => o.Number, 1).Set(o => o.Description, "002.thml");
  286. /// set作用:将指定TAggregate类型的实例对象的Number属性值更改为1,Description属性值改为"002.thml"
  287. /// 说明:Builders<TAggregate>.Update返回类型为UpdateDefinitionBuilder<TAggregate>,这个类有很多静态
  288. /// 方法,Set()是其中一个,要求传入一个func的表达示,以指示当前要修改的,TAggregate类型中的属性类型,
  289. /// 另一个参数就是这个属性的值。
  290. ///
  291. /// Builders<TAggregate>类有很多属性,返回很多如UpdateDefinitionBuilder<TAggregate>的很有用帮助类型
  292. /// 可以能参CSharpDriver-2.2.3.chm文件 下载MongoDB-CSharpDriver时带有些文件
  293. /// 或从官网https://docs.mongodb.com/ecosystem/drivers/csharp/看看
  294. ///
  295. /// </summary>
  296. /// <param name="filter">过滤条件</param>
  297. /// <param name="set">修改设置</param>
  298. public void Update(Expression<Func<TAggregate, bool>> filter, UpdateDefinition<TAggregate> set)
  299. {
  300. if (set == null)
  301. return;
  302. if (IsUseTransaction)//如果启用事务
  303. {
  304. try
  305. {
  306. beforeChange.Add(Collection.Find(filter).FirstOrDefault());
  307. writers.Add(new UpdateManyModel<TAggregate>(Builders<TAggregate>.Filter.Where(filter), set));
  308. isRollback = false;//不回滚
  309. return;//不执行后继操作
  310. }
  311. catch (Exception ex)
  312. {
  313. isRollback = true;
  314. throw new Exception(ex.Message);
  315. }
  316. }
  317. try
  318. {
  319. Collection.UpdateMany(filter, set);
  320. }
  321. catch (Exception ex)
  322. {
  323. throw new Exception(ex.Message);
  324. }
  325. }
  326. /// <summary>
  327. /// 过滤数据,执行更新操作(如不便使用,请用Replace相关的方法代替)
  328. ///
  329. /// 一般用replace来代替这个方法。其实这个功能还算强大的,可以很自由修改多个属性
  330. /// 关健是set参数比较不好配置,并且如果用此方法,调用端必须引用相关的DLL,set举例如下
  331. /// set = Builders<TAggregate>.Update.Update.Set(o => o.Number, 1).Set(o => o.Description, "002.thml");
  332. /// set作用:将指定TAggregate类型的实例对象的Number属性值更改为1,Description属性值改为"002.thml"
  333. /// 说明:Builders<TAggregate>.Update返回类型为UpdateDefinitionBuilder<TAggregate>,这个类有很多静态
  334. /// 方法,Set()是其中一个,要求传入一个func的表达示,以指示当前要修改的,TAggregate类型中的属性类型,
  335. /// 另一个参数就是这个属性的值。
  336. ///
  337. /// Builders<TAggregate>类有很多属性,返回很多如UpdateDefinitionBuilder<TAggregate>的很有用帮助类型
  338. /// 可以能参CSharpDriver-2.2.3.chm文件 下载MongoDB-CSharpDriver时带有些文件
  339. /// 或从官网https://docs.mongodb.com/ecosystem/drivers/csharp/看看
  340. ///
  341. /// </summary>
  342. /// <param name="id">找出指定的id数据</param>
  343. /// <param name="set">修改设置</param>
  344. public void Update(Guid id, UpdateDefinition<TAggregate> set)
  345. {
  346. if (set == null)
  347. return;
  348. if (IsUseTransaction)//如果启用事务
  349. {
  350. try
  351. {
  352. beforeChange.Add(Collection.Find(Builders<TAggregate>.Filter.Eq(o => o.Id, id)).FirstOrDefault());
  353. writers.Add(new UpdateManyModel<TAggregate>(Builders<TAggregate>.Filter.Eq(o => o.Id, id), set));
  354. isRollback = false;//不回滚
  355. return;//不执行后继操作
  356. }
  357. catch (Exception ex)
  358. {
  359. isRollback = true;
  360. throw new Exception(ex.Message);
  361. }
  362. }
  363. try
  364. {
  365. Collection.UpdateMany(o => o.Id == id, set);
  366. }
  367. catch (Exception ex)
  368. {
  369. throw new Exception(ex.Message);
  370. }
  371. }
  372. #endregion
  373.  
  374. #region 事务控制
  375. public void Commit()
  376. {
  377. )//如果不回滚,并且writers有数据
  378. {
  379. BulkWriteResult<TAggregate> result;
  380. try
  381. {
  382. result = Collection.BulkWrite(writers);
  383. }
  384. catch (Exception)
  385. {
  386. Rollback();//若BulkWriteResult发生异常
  387. throw;
  388. }
  389. if(result.ProcessedRequests.Count!=writers.Count)//检查完成写入的数量,如果有误,回滚
  390. {
  391. Rollback();
  392. }
  393. writers.Clear();//此时说明已成功提交,清空writers数据
  394. return;
  395. }
  396. Rollback();
  397. }
  398. public void Rollback()
  399. {
  400. writers.Clear();//清空writers
  401. //执行反操作
  402. beforeDelete.ForEach(o =>
  403. {
  404. Collection.InsertOne(o);
  405. });
  406. beforeChange.ForEach(o =>
  407. {
  408. Collection.ReplaceOne(c => c.Id == o.Id, o);
  409. });
  410. beforeAdd.ForEach(o =>
  411. {
  412. Collection.DeleteOne(d => d.Id == o);
  413. });
  414.  
  415. }
  416. #endregion
  417.  
  418. #region 查询
  419. /// <summary>
  420. /// 查找所有数据集合
  421. /// </summary>
  422. /// <returns></returns>
  423. public IQueryable<TAggregate> FindAll()
  424. {
  425. return Collection.AsQueryable();
  426. }
  427. /// <summary>
  428. /// 根据Id查找一条数据
  429. /// </summary>
  430. /// <param name="id"></param>
  431. /// <returns></returns>
  432. public TAggregate FindById(Guid id)
  433. {
  434. var find = Collection.Find(o => o.Id == id);
  435. if (!find.Any())
  436. return null;
  437. return find.FirstOrDefault();
  438. }
  439. /// <summary>
  440. /// 根据过滤条件找出符合条件的集合
  441. /// </summary>
  442. /// <param name="filter"></param>
  443. /// <returns></returns>
  444. public List<TAggregate> FindByFilter(Expression<Func<TAggregate, bool>> filter)
  445. {
  446. var find = Collection.Find(filter);
  447. if (!find.Any())
  448. return null;
  449. return find.ToList();
  450. }
  451. /// <summary>
  452. /// 根据过滤条件找出一条数据
  453. /// </summary>
  454. /// <param name="filter"></param>
  455. /// <returns></returns>
  456. public TAggregate FindOne(Expression<Func<TAggregate, bool>> filter)
  457. {
  458. return Collection.Find(filter).FirstOrDefault();
  459. }
  460. #endregion
  461.  
  462. /// <summary>
  463. /// 根据聚合类ID添加导航数据到 导航集合(中间表)
  464. /// </summary>
  465. /// <typeparam name="TNav">导航类</typeparam>
  466. /// <param name="nav">提供参数时直接new一个具体的nav类就行了</param>
  467. /// <param name="filter"></param>
  468. /// <param name="foreignKey"></param>
  469. public void AddByAggregate<TNav>(TNav nav, Expression<Func<TAggregate, bool>> filter, Guid foreignKey)
  470. where TNav : NavgationBase
  471. {
  472. //导航类的集合
  473. var navCollection = MongoDbContext.GetMongoCollection<TNav>(typeof(TNav).Name);
  474. //遍历当前集合中所有符合条件的数据
  475. Collection.Find(filter).ToList().ForEach(o =>
  476. {
  477. //将导航类的属性赋相应的值
  478. nav.AggregateId = foreignKey;
  479. nav.ValueObjectId = o.Id;
  480.  
  481. //插入到数据库
  482. navCollection.InsertOne(nav);
  483. });
  484. }
  485.  
  486. }
  487. }

6.测试一下   马上就要上班了,我也不啰嗦了,有注释

  1. using EFAndMongoRepostory;
  2. using EFAndMongoRepostory.Entity;
  3. using MongoDB.Driver;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7.  
  8. namespace MongoTest
  9. {
  10. class Program
  11. {
  12. static void Main(string[] args)
  13. {
  14.  
  15. #region 初始化
  16. var db = MongoDbContext.SetMongoDatabase("mongodb://localhost:27017", "MongoTest");
  17. #endregion
  18.  
  19. #region 准备数据
  20. List<Role> rList = new List<Role>
  21. {
  22. new Role
  23. {
  24. Name="r001", Description="rd001"
  25. },
  26. new Role
  27. {
  28. Name="r002",Description="rd002"
  29. },
  30. new Role
  31. {
  32. Name="r003",Description="rd003"
  33. }
  34. };
  35. List<User> uList = new List<User>
  36. {
  37. new User
  38. {
  39. Name=", Pwd="pwd001"
  40. },
  41. new User
  42. {
  43. Name=", Pwd="pwd002"
  44. }
  45. ,
  46. new User
  47. {
  48. Name=", Pwd="pwd003"
  49. }
  50. ,
  51. new User
  52. {
  53. Name=", Pwd="pwd004"
  54. }
  55. };
  56. List<Permission> pList = new List<Permission>
  57. {
  58. ", Url="001.html" },
  59. ", Url="002.html" },
  60. ", Url="003.html" },
  61. ", Url="004.html" },
  62. ", Url="005.html" }
  63. };
  64. #endregion
  65.  
  66. MongoRepostory<User> repostory = new MongoRepostory<User>();
  67. //清空集合
  68. db.DropCollection(typeof(User).Name);
  69.  
  70. //执行一次批量添加
  71. repostory.Add(uList);
  72.  
  73. //提交后查询所有数据
  74. repostory.Commit();
  75. repostory.FindAll().ToList().ForEach(o =>
  76. {
  77. Console.WriteLine(o.Name + ":" + o.Pwd + ":" + o.Number);
  78. });
  79.  
  80. //执行一次插入操作
  81. repostory.Add( });
  82.  
  83. //执行一次替换操作
  84. ");
  85. user.Pwd = ; user.Name = "u001";
  86. repostory.ReplaceOne(o => o.Name == ", user);
  87.  
  88. );
  89. );
  90. );
  91.  
  92. //执行3次更新操作
  93. repostory.Update(o => o.Name == ", update2);
  94. repostory.Update(o => o.Name == ", update3);
  95. repostory.Update(o => o.Name == ", update4);
  96.  
  97. //执行一次删除操作
  98. ");
  99. repostory.Remoe(o => o.Id==u.Id);
  100.  
  101. //提交
  102. repostory.Commit();
  103.  
  104. //查询所有数据
  105. repostory.FindAll().ToList().ForEach(o =>
  106. {
  107. Console.WriteLine(o.Name + ":" + o.Pwd + ":" + o.Number);
  108. });
  109.  
  110. //执行回滚
  111. repostory.Rollback();
  112. //查询所有数据
  113. Console.WriteLine("--------------------回滚到原来,应该是空的-----------------------------");
  114. repostory.FindAll().ToList().ForEach(o =>
  115. {
  116. Console.WriteLine(o.Name + ":" + o.Pwd + ":" + o.Number);
  117. });
  118.  
  119. Console.ReadKey();
  120. }
  121.  
  122. }
  123.  
  124. }

7. 关于@ wtsheng88的问题  本身存在那个问题的几率应该不是很大吧,如果实在要解决,我的思路是,把最后一次操作的元数据保存到一个备份数据库中,下次开机的时候先从备份中对比现在的数据库,如果存在不同,说明上次停电的时候没有完成,更新现在的数据库。而这些操作应该单独封装成一个静态方法,以便程序开始时就可以执行,在回滚操作中也可以调用。不行,没时间了

8.我要迟到了  还是那句话:都是个人自发研究、测试的,如有雷同,不胜荣幸;如觉不妥,留言喷射;如有错误,还请赐教;如获帮助,示意欣赏。新版中有很多异步操作,本人对此没作研究,怕会产生数据安全问题,所以全部用的是同步方法。

看门外汉如何实现:C#操作 MongoDB基本CURD的事务控制之 第二部分的更多相关文章

  1. 看门外汉如何实现:C#操作 MongoDB基本CURD的事务控制

    第一部分 基本设计 目前最新版本的C#驱动MongoDB-CSharpDriver-2.2.3,比之前的版本更新比较大,在网上很难找到这个版本的相关C#操作资料,以下都是个人自发研究.测试的,如有雷同 ...

  2. Python操作MongoDB看这一篇就够了

    MongoDB是由C++语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似JSON对象,它的字段值可以包含其他文档.数组及文档数组,非常灵活.在这一节中,我们就来看 ...

  3. JAVA操作MongoDB数据库

    1. 首先,下载MongoDB对Java支持的驱动包 驱动包下载地址:https://github.com/mongodb/mongo-java-driver/downloads 2.Java操作Mo ...

  4. 学习MongoDB--(11):应用举例(利用java操作MongoDB)

    原文地址:http://blog.csdn.net/drifterj/article/details/7948090 目录地址:http://blog.csdn.net/DrifterJ/articl ...

  5. Mongodb快速入门之使用Java操作Mongodb

    [IT168 专稿]在上一篇文章中,我们学习了Mongodb的安装和初步使用,在本文中,将学习如何使用Java去编程实现对Mongodb的操作. HelloWorld程序 学习任何程序的第一步,都是编 ...

  6. node.js高效操作mongodb

    node.js高效操作mongodb Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,类似ORM,Mongoose将数据库中的数据转换为Jav ...

  7. MongoDB的安装与python操作MongoDB

    一.安装MongoDB 因为我个人使用的是windows,就只记录下windows下的安装 1.下载安装 就是官网,下载msi,选个路径安装 2.配置 看见别的地方说需要手动在bin同级目录创建dat ...

  8. Node操作MongoDB并与express结合实现图书管理系统

    Node操作MongoDB数据库 原文链接:http://www.xingxin.me/ Web应用离不开数据库的操作,我们将陆续了解Node操作MongoDB与MySQL这是两个具有代表性的数据库, ...

  9. java操作mongodb(连接池)(转)

    原文链接: java操作mongodb(连接池) Mongo的实例其实就是一个数据库连接池,这个连接池里默认有10个链接.我们没有必要重新实现这个链接池,但是我们可以更改这个连接池的配置.因为Mong ...

随机推荐

  1. 广播变量、累加器、collect

    广播变量.累加器.collect spark集群由两类集群构成:一个驱动程序,多个执行程序. 1.广播变量 broadcast 广播变量为只读变量,它由运行sparkContext的驱动程序创建后发送 ...

  2. 在IE8中使用padding设置select控件文字垂直居中

    在火狐.苹果.谷歌.欧鹏等主流浏览器中,select下拉表单的文字能够垂直居中,如图: 而在ie8中,select下拉表单的文字基本就是靠底部显示,如图: 那么,如何使得ie8下的select文字垂直 ...

  3. android-Activity(四大组件之一)

    一.Activity理解 1.定义: 直译为活动,是Android定义四大应用组件之一,也是最重要的用的最多的: 用来提供一个能让用户操作并与之交互的界面 一个应用有多个界面也就是包含多个Activi ...

  4. poj1068 模拟

    Parencodings Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25010   Accepted: 14745 De ...

  5. centos6 系统优化脚本

    #!/bin/bash # 检查是否为root用户,脚本必须在root权限下运行 # if [[ "$(whoami)" != "root" ]]; then ...

  6. IOS第11天(3:UIPickerView省市联动)

    ********* #import "ViewController.h" #import "Province.h" @interface ViewControl ...

  7. 【应用笔记】【AN004】VB环境下基于RS-485的4-20mA电流采集

    版本:第一版作者:周新稳 杨帅 日期:20160226 =========================== 本资料高清PDF 下载: http://pan.baidu.com/s/1c1uuhLQ ...

  8. Nginx + php-fpm 执行 PHP 脚本超时 报错 502 Bad Gateway + 504 Gateway Time-out 的解决办法

    上周写好的发送邮件的计划任务只发送了一部分,检查计划任务日志,发现 502 Bad Gateway 的错误(已经在脚本中设置了 set_time_limit(0)). 后来在网上查找资料,可以通过以下 ...

  9. java notify和notifyAll的区别

    首先从名字可以了解,notify是通知一个线程获取锁,notifyAll是通知所有相关的线程去竞争锁. notify不能保证获得锁的线程,真正需要锁,并且可能产生死锁. 举例1: 所有人(消费者线程) ...

  10. spring boot servlet、filter、listener

    http://blog.csdn.net/catoop/article/details/50501686