MongoDB 学习笔记
前言:MongoDB 是目前在IT行业非常流行的一种非关系型数据库(NoSql),Mongo DB很好的实现了面向对象的思想(OO思想),在Mongo DB中 每一条记录都是一个Document对象。Mongo DB最大的优势在于所有的数据持久操作都无需开发人员手动编写SQL语句,直接调用方法就可以轻松的实现CRUD(增删改查)操作。
一.准备工作
1.下载MogonDB文件包,百度云地址:链接:http://pan.baidu.com/s/1kT7YB9X 密码:lq0q
2.压缩您刚才下载的MongoDB的zip压缩包,进入解包的bin目录,然后Windows+R 快捷键调出命令行窗口并切换到刚才的bin目录,然后输入以下命令:
这里我们运行了Mongod.exe,并指定了数据文件的保存目录(当然这个目录要实现建立好),看到了这个界面,那么表示MongoDB的服务端已成功启动了。
接下来,我们还要去下载MongoDB的C#驱动,它可以让我们在C#中使用MongoDB 。下载地址: https://github.com/samus/mongodb-csharp
我下载到的压缩包是:mongodb-csharp-master.zip。我们在C#访问MongoDB所需的驱动就是类库项目MongoDB了。编译这个项目就能得到了,文件名:MongoDB.dll
二.调用MongoDB
1)在C#中使用(建立一个测试程序)
1.接下来,本文演示通过C#完成【客户资料】的一些基本的数据操作,还是先来定义一个客户资料的类
public class Customer { [MongoId] public string CustomerID { get; set; } public string CustomerName { get; set; } public string ContactName { get; set; } public string Address { get; set; } public string PostalCode { get; set; } public string Tel { get; set; } }
MongoDB在使用前,并不要求您事先创建好相应的数据库,设计数据表结构。
在MongoDB中,没有【表】的概念,取而代之的是【集合】,也没有【数据记录】的概念,取而代之的是【文档】, 我们可以把【文档】理解成一个【对象】,任意的对象,甚至可以有复杂的嵌套层次。
因此,我们不用再写代码从【数据表字段】到C#类的【属性,字段】的转换了,现在直接就可以读写整个对象了。
而且MongoDB不支持Join操作,所以,如果有【关联】操作,就需要你自己来处理。
下面来定义C#的增删改查操作:
/// <summary> /// 数据实体类 /// </summary> public class Customer { [MongoId]//此处的特性驱动程序将把CustomerID映射为"_id"来使用 也就是说此处的CustomerID的值无论你写不写 无论你写什么 //最后得到的都是一个_id 然后CustomerID会不存在了 而主键值就变成了_id public string CustomerID { get; set; } public string CustomerName { get; set; } public string ContactName { get; set; } public string Address { get; set; } public string PostalCode { get; set; } public string Tel { get; set; } public override string ToString() { return string.Format("CustomerID:{0},CustomerName:{1},ContactName:{2},Address:{3},PostalCode:{4},Tel:{5}", CustomerID, CustomerName, ContactName, Address, PostalCode, Tel); } }
/// <summary> /// 对MongoDB和MongoDb的包装类 /// </summary> public class MyMongoDb : IDisposable { public void Dispose() { if (_mongo != null) { _mongo.Dispose(); _mongo = null; } } private Mongo _mongo; private IMongoDatabase _db; public MyMongoDb() : this("Server=127.0.0.1", "MyDB") { } /// <summary> /// 构造函数。根据指定连接字符串和数据库名 /// </summary> /// <param name="connectionString">连接字符串</param> /// <param name="dbName">数据库名,可为空,但必须在任何操作数据库之前要调用UseDb()方法</param> public MyMongoDb(string connectionString, string dbName) { if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException("connectionString"); _mongo = new Mongo(connectionString); // 立即连接 MongoDB _mongo.Connect(); if (string.IsNullOrEmpty(dbName) == false) _db = _mongo.GetDatabase(dbName); } /// <summary> /// 切换到指定的数据库 /// </summary> /// <param name="dbName"></param> /// <returns></returns> public IMongoDatabase UseDb(string dbName) { if (string.IsNullOrEmpty(dbName)) throw new ArgumentNullException("dbName"); _db = _mongo.GetDatabase(dbName); return _db; } /// <summary> /// 获取当前连接的数据库 /// </summary> public IMongoDatabase CurrentDb { get { if (_db == null) throw new Exception("当前连接没有指定任何数据库。请在构造函数中指定数据库名或者调用UseDb()方法切换数据库。"); return _db; } } /// <summary> /// 获取当前连接数据库的指定集合【依据类型】 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public IMongoCollection<T> GetCollection<T>() where T : class { return this.CurrentDb.GetCollection<T>(); } /// <summary> /// 获取当前连接数据库的指定集合【根据指定名称】 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name">集合名称</param> /// <returns></returns> public IMongoCollection<T> GetCollection<T>(string name) where T : class { return this.CurrentDb.GetCollection<T>(name); } } public class Handle { public string Insert(Customer customer) { customer.CustomerID = Guid.NewGuid().ToString("N"); using (MyMongoDb mm = new MyMongoDb()) { mm.GetCollection<Customer>().Insert(customer); } return customer.CustomerID; } public void Delete(string customerId) { using (MyMongoDb mm = new MyMongoDb()) { mm.GetCollection<Customer>().Remove(c => c.CustomerID == customerId); } } public string Update(Customer customer) { using (MyMongoDb mm = new MyMongoDb()) { mm.GetCollection<Customer>().Update(customer, (c => c.CustomerID == customer.CustomerID)); } return customer.CustomerID; } public Customer GetCustomerById(string customerId) { using (MyMongoDb mm = new MyMongoDb()) { return mm.GetCollection<Customer>().FindOne(c => c.CustomerID == customerId); } } }
接下来我们调用一下:
class Program { static void Main(string[] args) { Handle hd = new Handle(); string id1 = hd.Insert(new Customer() { CustomerID="001",Address = "bj1", ContactName = "cn1", CustomerName = "name1", PostalCode = "1", Tel = "10086" }); Console.WriteLine(hd.GetCustomerById(id1).ToString()); string id2 = hd.Insert(new Customer() { CustomerID="002",Address = "bj2", ContactName = "cn2", CustomerName = "name2", PostalCode = "2", Tel = "10086" }); Console.WriteLine(hd.GetCustomerById(id2).ToString()); string id3 = hd.Update(new Customer() { CustomerID = id1, Address = "bj2", ContactName = "cn2", CustomerName = "name2", PostalCode = "2", Tel = "10086" }); Console.WriteLine(hd.GetCustomerById(id3).ToString()); hd.Delete(id3); if (hd.GetCustomerById(id3) == null) { Console.WriteLine("删除Id为" + id3 + "的数据成功!"); } else { Console.WriteLine(hd.GetCustomerById(id3).ToString()); } Console.Read(); } }
输出结果如下:
2)使用MongoDB的客户端
2.1)查看数据
MongoDB自带一个Javascript shell,它可以从命令行与MongoDB实例交互。这个shell非常有用,通过它可以管理操作、检查运行实例、查询数据等操作。
让我们再回到命令行窗口模式下吧(没办法,MongoDB只提供这种界面),运行mongo.exe ,如下:
这就是MongoDB的客户端的命令行模式了。通常我们在操作数据库前,要切换【当前数据】,
MongoDB也是一样,我们可以运行如下命令来查看数据库列表,并切换数据库,然后再查看集合列表,请看下图(我运行了三条命令):
注意:MongoDB区分名字的大小写。
在MongoDB中,查看【当前数据库】,可以使用命令【db】,
查看集合Customer的记录总数:【db.Customer.count();】
查看 CustomerId = 41c0a06fcc414639843deb281cc214c7 的记录:【db.Customer.findOne({"_id" : "41c0a06fcc414639843deb281cc214c7"});】,注意:查询条件是一个文档,这就是MongoDB的特色。
下图显示了上面三条命令的执行结果:
注意:此处如果你查询的字符串中有汉字乱码情况那么考虑这个问题是和cmd.exe有关。
2.2)维护数据
下面我来演示一下如何使用MongoDB的客户端来执行一些基本的数据维护功能。还是从CRUD操作开始吧,请看下图,为了方便,我将在一个截图中执行多个命令。
注意:MongoDB的文档使用的是一种称为BSON格式的对象,与Javascript中的JSON类似。
在示例中,我先切换到 MyTest 数据库(它并不存在,但没关系), 然后我定义了一个文档 item 并插入到集合 table1 中,然后又定义了一个文档 item2,也插入到集合 table1 中。此时,您有没有注意到:【每个文档有一个名为 "_id" 的成员】,我并没有定义。
其实,MongoDB会为每个文档都创建这样一个文档成员,我们指定的 "key"对于MongoDB来说: 它们并不是【文档的主键】,MongoDB只认 "_id",你可以指定,但如果不指定,MongoDB就自动添加。此时也解答了为什么在用C#代码实现CRUD操作时候会有一个MongoId的特性。正是由于这个特性,驱动程序将把CustomerID映射为"_id"来使用。
为了要更新某个文档,我们要使用findOne()方法找到要修改的文档对象,并将它保存一个变量t中,然后,修改它的属性, 接着调用update()方法就可以更新文档了,注意在调用update()时,第一个参数【更新范围】是采用文档的形式给出的, 第二参数才是要更新的新对象。在删除时,删除条件也是采用文档的形式指定的。处处使用文档,这就是MongoDB的特色:
前面用的find()和findOne(),它们是有区别的:findOne()只返回一个文档对象,find()返回一个集合列表, 如果不指定过滤范围,它将返回整个集合,但在客户端中最多只显示前20个文档。
当然MongoDB的东西还有很多,我也是初认识,以后再多多研究吧。