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的东西还有很多,我也是初认识,以后再多多研究吧。

posted @ 2015-07-12 14:33  My Way!  阅读(340)  评论(0编辑  收藏  举报