Node.js 蚕食计划(六)—— MongoDB + Koa 入门
<p><span style="font-size: 16px"><strong>一、安装 MongoDB</strong></span></p><p><span style="font-size: 14px"><strong>1. 在 Windows 环境下安装:</strong></span></p>
<p><span style="color: rgba(136, 136, 136, 1); font-size: 14px">// Windows 7 / Server 2008 R2 以上的版本</span></p>
<p><span style="font-size: 14px">打开官网链接 https://www.mongodb.com/try/download/community</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200710150009923-542264779.png" alt="" width="1159" height="502" loading="lazy"></span></p>
<p><span style="font-size: 14px">在页面中依次选择 <span style="color: rgba(0, 128, 128, 1)">On-Premises</span> => <span style="color: rgba(0, 128, 128, 1)">MongoDB Communtiy Server</span>,然后选择 <span style="color: rgba(0, 128, 128, 1)">Platform</span> 为 Windows,最后下载并执行安装包</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"><strong>1. 在 MacOS 安装:</strong> </span></p>
<p><span style="font-size: 14px">也可以按照上面的方法下载安装包,或者选择 <span style="color: rgba(0, 128, 128, 1)">Download</span> 按钮旁的 <span style="color: rgba(0, 128, 128, 1)"><strong>Copy Link</strong></span>,通过 curl 命令安装</span></p>
<p><span style="font-size: 14px">不过还有另一种不需要打开 MongoDB 官网的办法:<span style="color: rgba(128, 0, 0, 1)">直接使用 brew 安装<span style="color: rgba(0, 0, 0, 1)">(参考链接)<br></span></span></span></p>
<p><span style="font-size: 14px">首先 tab 仓库</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">brew tap mongodb/brew</span></pre>
</div>
<p><span style="font-size: 14px">然后安装社区版本</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">brew install mongodb-community</span></pre>
</div>
<p><span style="font-size: 14px">安装的时候会自动创建配置文件:</span></p>
<ul>
<li><span style="font-size: 14px">配置文件: /usr/local/etc/mongod.conf</span></li>
<li><span style="font-size: 14px">日志目录: /usr/local/var/log/mongodb</span></li>
<li><span style="font-size: 14px">数据目录: /usr/local/var/mongodb</span></li>
</ul>
<p><span style="font-size: 14px">可以用 <span class="cnblogs_code">mongod --version</span> 命令来检查是否安装成功</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200710155355848-33485275.png" alt="" loading="lazy"></span></p>
<p><span style="font-size: 14px">如果能正常显示当前版本,就说明安装成功,可以直接进入下一节</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px">如果提示 "command not found: mongod" ,就得手动配置环境变量</span></p>
<p><span style="font-size: 14px">需要先找到 mongod 的安装位置,由于安装的版本不同,路径不会完全一致,可以一步一步的来找:</span></p>
<p><span style="font-size: 14px">先进入 Cellar 目录:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">cd /usr/local/Cellar</span></pre>
</div>
<p><span style="font-size: 14px">然后通过 ls 命令查看当前目录下的文件,然后进入带有 mongodb 的文件夹,然后逐步深入,直到进入 bin 文件夹,使用 pwd 命令查看完整路径</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200710161103513-528066918.png" alt="" loading="lazy"></span></p>
<p><span style="font-size: 14px">记下这个路径备用,打开环境变量配置文件</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">vim ~/.bash_profile</span></pre>
</div>
<p><span style="font-size: 14px">添加一行变量(把路径改成自己的路径)</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">export PATH=/usr/local/Cellar/mongodb-community/4.2.8/bin:${PATH}}</span></pre>
</div>
<p><span style="font-size: 14px">保存文件,执行以下命令</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">source ~/.bash_profile</span></pre>
</div>
<p><span style="font-size: 14px">然后就可以使用 mongod 命令了</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 16px"><strong>二、启动 MongoDB</strong></span></p>
<p><span style="font-size: 14px">如果直接启动</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">mongod</span></pre>
</div>
<p><span style="font-size: 14px">会直接报错 <span style="color: rgba(128, 0, 0, 1)">Data directory /data/db not found</span></span></p>
<p><span style="font-size: 14px">这是因为使用不带参数的 <span class="cnblogs_code">mongod</span> 命令会使用默认的数据目录 <span style="color: rgba(0, 128, 128, 1)">/data/db</span></span></p>
<p><span style="font-size: 14px">如果使用之前创建的配置文件启动就不会有问题:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">mongod --config /usr/local/etc/mongod.conf</span></pre>
</div>
<p><span style="font-size: 14px">如果觉得这样的启动命令很累赘,就创建一个 <span style="color: rgba(0, 128, 128, 1)">/data/db</span> 目录</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">sudo mkdir -p /data/db</span></pre>
</div>
<p><span style="font-size: 14px">然后就能使用 <span class="cnblogs_code">mongod</span> 命令启动了,</span></p>
<p><span style="color: rgba(128, 128, 128, 1); font-size: 14px">// 如果遇到 Address already in use 这个错误,是因为端口号占用,清理对应端口的 pid 即可</span></p>
<p><span style="font-size: 14px">可以在浏览器访问 <span class="cnblogs_code">localhost:<span style="color: rgba(128, 0, 128, 1)">27017</span></span> 确认是否成功启动</span></p>
<p><span style="font-size: 14px">如果需要关闭服务器,可以使用 <span style="color: rgba(128, 0, 0, 1)"><strong>Crtl + C</strong></span> 组合键</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px">这个启动 mongod 的终端可以放在一边了,新起一个终端,打开 MongoDB shell</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">mongo</span></pre>
</div>
<p><span style="font-size: 14px"><strong><span style="color: rgba(128, 0, 0, 1)">注意这个命令不是 <span style="color: rgba(0, 128, 128, 1)">mongod</span></span></strong></span></p>
<p><span style="font-size: 14px">在启动的 shell 里面输入 help,查看可用的命令</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200710174623778-786535540.png" alt="" width="1031" height="549" loading="lazy"></span></p>
<p><span style="font-size: 14px">如果不想使用命令行来操作 MongoDB,可以使用可视化工具,比如 Robomongo、Nosqlclient、Navicat</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 16px"><strong>三、MongoDB 创建数据</strong></span></p>
<p><span style="font-size: 14px">接下来在 MongoDB 中插入数据,首先创建一个数据库</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">use Movie</span></pre>
</div>
<p><span style="font-size: 14px">这里创建了一个名为 Movie 的数据库,但这时的 Movie 数据库还没有数据,所以 <span class="cnblogs_code">show dbs</span> 不会列出刚才创建的数据库</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200714155221743-21527290.png" alt="" width="257" height="162" loading="lazy"></span></p>
<p><span style="font-size: 14px"> 在当前数据库中创建一个集合,并插入一条数据</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">db.createCollection(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">movies</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
db.movies.insert({</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">让子弹飞</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">years</span><span style="color: rgba(128, 0, 0, 1)">"</span>:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">2010</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">director</span><span style="color: rgba(128, 0, 0, 1)">"</span>: [<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">姜文</span><span style="color: rgba(128, 0, 0, 1)">"</span>]})</span></pre>
</div>
<p><span style="color: rgba(128, 0, 0, 1); font-size: 14px"><strong>注意: 和创建数据库类似,在 MongoDB 中,创建集合后要再插入一个文档,集合才会真正创建</strong></span></p>
<p><span style="font-size: 14px">当插入了具体的数据之后,数据库才算创建完成,接下来了解一下基本的增删改查</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"><strong>1. 新增数据</strong></span></p>
<p><span style="font-size: 14px">在 MongoDB 中可以使用 <strong><span style="color: rgba(0, 128, 128, 1)">insert</span></strong> 向集合插入数据,每条新建的数据都会自动生成一个主键<span style="color: rgba(0, 128, 128, 1)"><strong> _id</strong></span></span></p>
<p><span style="font-size: 14px">使用 insert 插入数据时,如果没有携带主键 _id,则新增数据;</span></p>
<p><span style="font-size: 14px">如果携带了 _id 且 _id 没有重复,则新增一条自带 _id 的数据(不会自动生成 _id);</span></p>
<p><span style="font-size: 14px">如果携带了 _id 且 _id 冲突,则抛出“主键重复”的错误,保存失败。</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200714171523954-1936551188.png" alt="" width="950" height="194" loading="lazy"></span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"><strong>2. 查询数据</strong></span></p>
<p><span style="font-size: 14px">在 MongoDB 中查询数据一般使用 <span style="color: rgba(0, 128, 128, 1)"><strong>find</strong></span> 方法</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">db.movies.find().pretty()</span></pre>
</div>
<p><span style="font-size: 14px">这里的 pretty() 用来格式化查询结果</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200714191112713-458734688.png" alt="" width="512" height="55" loading="lazy"></span></p>
<p><span style="font-size: 14px">在查询条件中,还可以加入条件判断</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200714192015746-1411469718.png" alt="" width="918" height="303" loading="lazy"></span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"><strong>3. 更新数据</strong></span></p>
<p><span style="font-size: 14px">在 MongoDB 中使用 <span style="color: rgba(0, 128, 128, 1)"><strong>update</strong></span> 和 <strong><span style="color: rgba(0, 128, 128, 1)">replaceOne</span></strong> 来更新集合中的文档</span></p>
<p><span style="font-size: 14px">其中 update() 可以接收三个参数</span></p>
<p><span style="font-size: 14px">第一个参数为查询条件,和上面的 find 类似;</span></p>
<p><span style="font-size: 14px">第二个参数为操作符,比如 $set 用来设置新属性;</span></p>
<p><span style="font-size: 14px">第三个参数为配置项,暂时不提。</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200714193128047-1527204768.png" alt="" width="669" height="147" loading="lazy"></span></p>
<p><span style="font-size: 14px">这里我先新增了一条数据,然后通过 update 修改了这条数据的 name</span></p>
<p><span style="font-size: 14px">可以看到,只有 name 被修改了,years 并没有发生变化,也就是说 <span style="color: rgba(128, 0, 0, 1)"><strong><span style="color: rgba(0, 128, 128, 1)">update()</span> 的 <span style="color: rgba(0, 128, 128, 1)">$set</span> 只会合并相应的字段</strong></span></span></p>
<p><span style="color: rgba(128, 0, 0, 1); font-size: 14px"><strong>如果需要替换整条数据,可以用 <span style="color: rgba(0, 128, 128, 1)">replaceOne()</span></strong></span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200714193555936-372704854.png" alt="" width="986" height="159" loading="lazy"></span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"><strong>4. 删除数据</strong></span></p>
<p><span style="font-size: 14px">可以使用 <strong><span style="color: rgba(0, 128, 128, 1)">remove</span></strong> 来删除集合中的数据</span></p>
<p><span style="font-size: 14px">该方法和 <strong>find</strong> 类似,都是接受一个查询条件,然后从集合中删除查询到的文档</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200714194017281-1180398515.png" alt="" width="986" height="148" loading="lazy"></span></p>
<p><span style="font-size: 14px">remove 的 query 参数是必填的,<span style="color: rgba(128, 0, 0, 1)"><strong>如果往 remove 方法中传入的查询条件为空对象 {},会删除整个集合的数据</strong></span></span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200714194302577-1923550381.png" alt="" loading="lazy"></span></p>
<p><span style="font-size: 14px">另外, 可以使用 <span style="color: rgba(0, 128, 128, 1)"><strong>drop</strong></span> 来删除集合,<span style="color: rgba(0, 128, 128, 1)"><strong>dropDatabase</strong></span> 来删除数据库</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1); font-size: 14px">db.collection.drop()
db.dropDatabase()</span></pre>
</div>
<p><span style="font-size: 14px">关于 MongoDB 的介绍就到这里,深入了解可以参考 MongoDB 中文网 </span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 16px"><strong>四、在 Koa 中连接 MongoDB</strong></span></p>
<p><span style="font-size: 14px">先创建一个 Koa 项目,可以参考之前的文章《Node.js 蚕食计划(五)—— Koa 基础项目搭建》</span></p>
<p><span style="font-size: 14px">在项目的根目录创建一个 mongodb 目录,然后在该目录下新建 <span style="color: rgba(0, 128, 128, 1)"><strong>config.js</strong></span>,用来保存一些数据库常量配置</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> /mongodb/config.js</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> dbUrl = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">mongodb://127.0.0.1:27017</span><span style="color: rgba(128, 0, 0, 1)">'</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 数据库地址</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> dbName = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Movie</span><span style="color: rgba(128, 0, 0, 1)">'</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">数据库名称</span>
<span style="color: rgba(0, 0, 0, 1)">
module.exports </span>=<span style="color: rgba(0, 0, 0, 1)"> {
dbUrl,
dbName
}</span></span></pre>
</div>
<p><span style="font-size: 14px">然后安装 mongodb 中间件</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">yarn add mongodb</span></pre>
</div>
<p><span style="font-size: 14px">在 mongodb 目录下创建一个 <strong><span style="color: rgba(0, 128, 128, 1)">index.js</span></strong>,使用中间件连接 MongoDB 数据库</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> /mongodb/index.js</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> { MongoClient, ObjectID}= require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">mongodb</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">const</span> { dbUrl, dbName } = require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./config</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 连接数据库</span>
MongoClient.connect(dbUrl, (err, client) =><span style="color: rgba(0, 0, 0, 1)"> {
console.log(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Connected successfully to server</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">const</span> db =<span style="color: rgba(0, 0, 0, 1)"> client.db(dbName);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> db.close(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 关闭连接</span>
});</span></pre>
</div>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200715104836815-596248443.png" alt="" width="296" height="360" loading="lazy"></span></p>
<p><span style="font-size: 14px">我的项目结构是这样的,其中 app.js 是入口文件</span></p>
<p><span style="font-size: 14px">可以在 app.js 中 <span class="cnblogs_code">require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./mongodb</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</span> 直接引入刚才的 index.js,检查一下是否能够正常连接数据库</span></p>
<p><span style="font-size: 14px">启动项目,如果在 MongoDB 的终端看到连接的提示,则表示成功连接数据库</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200715105711072-239377511.png" alt="" width="885" height="41" loading="lazy"></span></p>
<p><span style="font-size: 14px"> </span></p>
<p> </p>
<p><span style="font-size: 16px"><strong>五、封装 MongoDB 类</strong></span></p>
<p><span style="font-size: 14px">实际场景中肯定不会每次查询都调用一次数据库,所以需要封装一个类,通过类的实例来操作数据库 </span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> /mongodb/index.js</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> { MongoClient, ObjectID } = require(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mongodb</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">const</span> Config = require(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">./config</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Db {
</span><span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> getInstance() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 单例模式 解决多次实例化 实例不共享的问题</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">Db.instance) {
Db.instance </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Db();
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Db.instance;
}
constructor() {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.dbClient = <span style="color: rgba(128, 0, 0, 1)">""</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">db对象</span>
<span style="color: rgba(0, 0, 255, 1)">this</span>.connect(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 实例化的时候就连接数据库</span>
<span style="color: rgba(0, 0, 0, 1)">}
connect() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 连接数据库</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.dbClient) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">解决数据库多次连接的问题</span>
MongoClient.connect(Config.dbUrl, { useUnifiedTopology: <span style="color: rgba(0, 0, 255, 1)">true</span> }, (err, client) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
reject(err);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.dbClient =<span style="color: rgba(0, 0, 0, 1)"> client.db(Config.dbName);
resolve(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.dbClient);
});
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
resolve(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.dbClient);
}
});
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">查找操作 collection:表名 json:查找条件</span>
<span style="color: rgba(0, 0, 0, 1)">find(collection, json) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.connect().then((db) =><span style="color: rgba(0, 0, 0, 1)"> {
let result </span>=<span style="color: rgba(0, 0, 0, 1)"> db.collection(collection).find(json);
result.toArray((err, docs) </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">err) {
resolve(docs);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
reject(err);
}
});
});
});
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新增操作</span>
<span style="color: rgba(0, 0, 0, 1)">insert(collection, json) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.connect().then((db) =><span style="color: rgba(0, 0, 0, 1)"> {
db.collection(collection).insertOne(json, (err, result) </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">err) {
resolve(result);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
reject(err);
}
});
});
});
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改操作</span>
<span style="color: rgba(0, 0, 0, 1)">update(collection, json1, json2) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.connect().then((db) =><span style="color: rgba(0, 0, 0, 1)"> {
db.collection(collection).updateOne(
json1,
{
$</span><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">: json2,
},
(err, result) </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">err) {
resolve(result);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
reject(err);
}
}
);
});
});
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">删除操作</span>
<span style="color: rgba(0, 0, 0, 1)">delete(collection, json) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve, reject) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.connect().then((db) =><span style="color: rgba(0, 0, 0, 1)"> {
db.collection(collection).removeOne(json, (err, result) </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">err) {
resolve(result);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
reject(err);
}
});
});
});
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">在进行查询或者删除操作的时候,我们一般都会通过id去进行操作,但是我们直接使用传递过来的id是不起作用的,需要使用mongodb提供的ObjectID方法,生成一个新的id去查询。</span>
<span style="color: rgba(0, 0, 0, 1)">getObjectID(id) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ObjectID(id);
}
}
module.exports </span>= Db.getInstance();</span></pre>
</div>
<p><span style="color: rgba(128, 128, 128, 1); font-size: 14px">// 代码摘自 https://juejin.im/post/5e4765626fb9a07cad3b93dc#heading-24</span></p>
<p><span style="font-size: 14px">封装好了,在 app.js 试试</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">...</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> bodyParser = require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">koa-bodyparser</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">const</span> DB = require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./mongodb</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);<br>
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">...</span>
<span style="color: rgba(0, 0, 0, 1)">
app.use(bodyParser());
router.post(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/save</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(0, 0, 255, 1)">async</span>(ctx, next) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">const</span> form =<span style="color: rgba(0, 0, 0, 1)"> ctx.request.body;
console.log(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">form------></span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, form);
</span><span style="color: rgba(0, 0, 255, 1)">const</span> result = <span style="color: rgba(0, 0, 255, 1)">await</span> DB.insert(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">movies</span><span style="color: rgba(128, 0, 0, 1)">'</span>, form); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 新增</span>
ctx.body =<span style="color: rgba(0, 0, 0, 1)"> result;
});
router.</span><span style="color: rgba(0, 0, 255, 1)">get</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/list</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(0, 0, 255, 1)">async</span>(ctx, next) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">const</span> result = <span style="color: rgba(0, 0, 255, 1)">await</span> DB.find(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">movies</span><span style="color: rgba(128, 0, 0, 1)">'</span>, {}); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查询</span>
ctx.body =<span style="color: rgba(0, 0, 0, 1)"> result;
});
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">...</span></span></pre>
</div>
<p><span style="font-size: 14px">上面引入了 <span style="color: rgba(0, 128, 128, 1)"><strong>koa-bodyparser </strong></span>来处理 POST 请求的参数</span></p>
<p><span style="font-size: 14px">然后写了一个新增数据的 post 接口 /save,和查询数据的 get 接口 /list</span></p>
<p><span style="font-size: 14px">接下来先用 PostMan 测试一下 /save 接口</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200715152124560-1876149032.png" alt="" width="739" height="178" loading="lazy"></span></p>
<p><span style="color: rgba(128, 0, 0, 1); font-size: 14px"><strong>这里传的参数是 JSON 格式,需要在 Headers 中设置 <span style="color: rgba(0, 128, 128, 1)">Content-Type</span> 为 <span style="color: rgba(0, 128, 128, 1)">application/json</span></strong></span></p>
<p><span style="font-size: 14px">如果设置为 application/x-www-form-urlencoded,就需要用 querystring 转码</span></p>
<p> </p>
<p><span style="font-size: 14px">保存成功之后,再试试 /list 接口</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202007/1059788-20200715152747144-583779149.png" alt="" width="607" height="481" loading="lazy"></span></p>
<p><span style="font-size: 14px">到这里一个简单的后端服务就搭好了</span></p>
<p><span style="font-size: 14px">但这里我们直接使用了 mongodb 中间件来连接数据库,对数据库的操作比较原始</span></p>
<p><span style="font-size: 14px">一个工程化的后端项目,通常会设计 Controller 来管理 API,还会通过 Schema 来规范集合</span></p>
<p><span style="font-size: 14px">这些都可以通过 使用 mongoose 来实现,在后面的文章中会介绍</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"><strong>参考资料:</strong></span></p>
<p><span style="font-size: 14px">《MongoDB 中文手册》</span></p>
<p><span style="font-size: 14px">《koa2 + jwt + mongodb入门实战》</span></p><br><br>
来源:https://www.cnblogs.com/wisewrong/p/13280266.html
頁:
[1]