mongoDB数据库基础入门教程 朴灿烈づ我的快乐病毒、 2023-01-11 08:55 108阅读 0赞 ### 1 数据库概述及环境搭建 ### #### 1.1 为什么要使用数据库 #### 大家先想一个问题,你在手机app的京东将商品加入到购物车中,那么在pc端登录京东后,购物车中商品还存在吗? 答案是肯定的,那数据存在哪了呢? 1. 数据库可以结构化存储大量的数据信息,方便用户进行有效的检索和访问。 2. 数据库可以有效地保持数据信息的一致性、完整性、降低数据冗余。 3. 数据库可以满足应用的共享和安全方面的要求,把数据放在数据库中在很多情况下也是出于安全的考虑。 4. 数据库技术能够方便智能化地分析,产生新的有用信息。 #### 1.2 什么是数据库 #### 数据库即存储数据的仓库,可以将数据进行有序的分门别类的存储。它是独立于语言之外的软件,可以通过API去操作它。 常见的数据库软件有:mysql、mongoDB、oracle。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center] #### 1.3mongoDB数据库下载安装 #### **下载** 下载地址:https://www.mongodb.com/download-center/community ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 1] **安装** 1. 我这里将下载的MongoDB放在D盘目录下:D:\\develop\\MongoDB ![在这里插入图片描述][20210126132851450.png_pic_center] 2. 接下来是安装,双击上面的.msi文件即可,所有步骤都有截图,注意红色方框位置 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 2] 1. 点击接受 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 3] 1. 选择Custom模式 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 4] 2. 更改安装路径 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 5] 3. 然后按照提示一直往下走 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 6] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 7] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 8] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 9] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 10] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 11] #### 1.4 mongoDB可视化软件★★★ #### MongoDB Compass Community由MongoDB开发人员开发,这意味着更高的可靠性和兼容性。它为MongoDB提供GUI mongodb工具,以探索数据库交互;具有完整的CRUD功能并提供可视方式。借助内置模式可视化,用户可以分析文档并显示丰富的结构。为了监控服务器的负载,它提供了数据库操作的实时统计信息。就像MongoDB一样,Compass也有两个版本,一个是Enterprise(付费),社区可以免费使用。适用于Linux,Mac或Windows。 下载地址:https://www.mongodb.com/download-center/compass ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 12] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 13] #### 1.5数据库相关概念 #### 在一个数据库软件中可以包含多个数据仓库,在每个数据仓库中可以包含多个数据集合,每个数据集合中可以包含多条文档(具体的数据)。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 14] #### 1.6mongoose第三方包 #### 使用Node.js操作MongoDB数据库需要依赖Node.js第三方包mongoose 使用 `npm install mongoose` 命令下载 #### 1.7启动mongoDB #### 在命令行工具中运行 `net start mongoDB` 即可启动MongoDB,否则MongoDB将无法连接 #### 1.8数据库连接 #### 使用mongoose提供的**connect**方法即可连接数据库。 mongoose.connect('mongodb://localhost/playground') .then(() => console.log('数据库连接成功')) .catch(err => console.log('数据库连接失败', err)); ### 2 **mongoDB数据库连接** ### #### 2.1 创建数据库 #### 在MongoDB中不需要显式创建数据库,如果正在使用的数据库不存在,MongoDB会自动创建。 ### 3 **mongoDB增删改查操作** ### #### 3.1创建集合 #### 创建集合分为两步,一是对**对集合设定规则**,二是**创建集合**,创建mongoose.Schema构造函数的实例即可创建集合 // 设定集合规则 const courseSchema = new mongoose.Schema({ name: String, author: String, isPublished: Boolean }); // 创建集合并应用规则 const Course = mongoose.model('Course', courseSchema); // courses #### 3.2创建文档 #### Course.create({ name: 'JavaScript基础', author: 'node讲师', isPublish: true}, (err, doc) => { // 错误对象 console.log(err) // 当前插入的文档 console.log(doc) }); Course.create({ name: 'JavaScript基础', author: 'node讲师', isPublish: true}) .then(doc => console.log(doc)) .catch(err => console.log(err)) #### 3.3mongoDB数据库导入数据 #### mongoimport –d 数据库名称 –c 集合名称 –file 要导入的数据文件 找到mongodb数据库的安装目录,将安装目录下的bin目录放置在环境变量中。 #### 3.4查询文档 #### //根据条件查找文档(条件为空则查找所有文档) Course.find().then(result => console.log(result)) //返回文档集合 [{ _id: 5c0917ed37ec9b03c07cf95f, name: 'node.js基础', author: 'node讲师‘ },{ _id: 5c09dea28acfb814980ff827, name: 'Javascript', author: 'node讲师‘ }] //根据条件查找文档 Course.findOne({ name: 'node.js基础'}).then(result => console.log(result)) //返回文档 { _id: 5c0917ed37ec9b03c07cf95f, name: 'node.js基础', author: 'node讲师‘ } //匹配大于 小于 User.find({ age: { $gt: 20, $lt: 50}}).then(result => console.log(result)) //匹配包含 User.find({ hobbies: { $in: ['敲代码']}}).then(result => console.log(result)) //选择要查询的字段 User.find().select('name email').then(result => console.log(result)) //将数据按照年龄进行排序 User.find().sort('age').then(result => console.log(result)) //skip 跳过多少条数据 limit 限制查询数量 User.find().skip(2).limit(2).then(result => console.log(result)) #### 3.5删除文档 #### //删除单个 Course.findOneAndDelete({ }).then(result => console.log(result)) //删除多个 User.deleteMany({ }).then(result => console.log(result)) #### 3.6更新文档 #### //更新单个 User.updateOne({ 查询条件}, { 要修改的值}).then(result => console.log(result)) //更新多个 User.updateMany({ 查询条件}, { 要更改的值}).then(result => console.log(result)) #### 3.7mongoose验证 #### 在创建集合规则时,可以设置当前字段的验证规则,验证失败就则输入插入失败 * lrequired: true 必传字段 * lminlength:3 字符串最小长度 * lmaxlength: 20 字符串最大长度 * lmin: 2 数值最小为2 * lmax: 100 数值最大为100 * lenum: \[‘html’**,** ‘css’**,** ‘javascript’**,** ‘node.js’\] * ltrim: true 去除字符串两边的空格 * lvalidate: 自定义验证器 * ldefault: 默认值 获取错误信息:error.errors\[‘字段名称’\].message #### 3.8集合关联 #### 通常**不同集合的数据之间是有关系的**,例如文章信息和用户信息存储在不同集合中,但文章是某个用户发表的,要查询文章的所有信息包括发表用户,就需要用到集合关联。 * 使用id对集合进行关联 * 使用populate方法进行关联集合查询 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 15] // 用户集合 const User = mongoose.model('User', new mongoose.Schema({ name: { type: String } })); // 文章集合 const Post = mongoose.model('Post', new mongoose.Schema({ title: { type: String }, // 使用ID将文章集合和作者集合进行关联 author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' } })); //联合查询 Post.find() .populate('author') .then((err, result) => console.log(result)); ### 4 **案例讲解-用户信息CRUD** ### #### 4.1 添加 #### <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h3>添加用户</h3> <form method="post" action="/add"> <div class="form-group"> <label>用户名</label> <input name="name" type="text" class="form-control" placeholder="请填写用户名"> </div> <div class="form-group"> <label>密码</label> <input name="password" type="password" class="form-control" placeholder="请输入密码"> </div> <div class="form-group"> <label>年龄</label> <input name="age" type="text" class="form-control" placeholder="请填写邮箱"> </div> <div class="form-group"> <label>邮箱</label> <input name="email" type="email" class="form-control" placeholder="请填写邮箱"> </div> <div class="form-group"> <label>请选择爱好</label> <div> <label class="checkbox-inline"> <input type="checkbox" value="足球" name="hobbies"> 足球 </label> <label class="checkbox-inline"> <input type="checkbox" value="篮球" name="hobbies"> 篮球 </label> <label class="checkbox-inline"> <input type="checkbox" value="橄榄球" name="hobbies"> 橄榄球 </label> <label class="checkbox-inline"> <input type="checkbox" value="敲代码" name="hobbies"> 敲代码 </label> <label class="checkbox-inline"> <input type="checkbox" value="抽烟" name="hobbies"> 抽烟 </label> <label class="checkbox-inline"> <input type="checkbox" value="喝酒" name="hobbies"> 喝酒 </label> <label class="checkbox-inline"> <input type="checkbox" value="烫头" name="hobbies"> 烫头 </label> </div> </div> <button type="submit" class="btn btn-primary">添加用户</button> </form> </div> </body> </html> if (pathname == '/add') { // 接受用户提交的信息 let formData = ''; // 接受post参数 req.on('data', param => { formData += param; }) // post参数接受完毕 req.on('end', async () => { let user = querystring.parse(formData) // 将用户提交的信息添加到数据库中 await User.create(user); // 301代表重定向 // location 跳转地址 res.writeHead(301, { Location: '/list' }); res.end(); }) } #### 4.2 删除 #### if (pathname == '/remove') { // res.end(query.id) await User.findOneAndDelete({ _id: query.id}); res.writeHead(301, { Location: '/list' }); res.end(); } #### 4.3 更新 #### if (pathname == '/modify') { let user = await User.findOne({ _id: query.id}); let hobbies = ['足球', '篮球', '橄榄球', '敲代码', '抽烟', '喝酒', '烫头', '吃饭', '睡觉', '打豆豆'] console.log(user) // 呈现修改用户表单页面 let modify = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h3>修改用户</h3> <form method="post" action="/modify?id=${ user._id}"> <div class="form-group"> <label>用户名</label> <input value="${ user.name}" name="name" type="text" class="form-control" placeholder="请填写用户名"> </div> <div class="form-group"> <label>密码</label> <input value="${ user.password}" name="password" type="password" class="form-control" placeholder="请输入密码"> </div> <div class="form-group"> <label>年龄</label> <input value="${ user.age}" name="age" type="text" class="form-control" placeholder="请填写邮箱"> </div> <div class="form-group"> <label>邮箱</label> <input value="${ user.email}" name="email" type="email" class="form-control" placeholder="请填写邮箱"> </div> <div class="form-group"> <label>请选择爱好</label> <div>`; hobbies.forEach(item => { // 判断当前循环项在不在用户的爱好数据组 let isHobby = user.hobbies.includes(item); if (isHobby) { modify += ` <label class="checkbox-inline"> <input type="checkbox" value="${ item}" name="hobbies" checked> ${ item} </label> ` }else { modify += ` <label class="checkbox-inline"> <input type="checkbox" value="${ item}" name="hobbies"> ${ item} </label> ` } }) modify += ` </div> </div> <button type="submit" class="btn btn-primary">修改用户</button> </form> </div> </body> </html> `; res.end(modify) #### 4.4 查询 #### if (method == 'GET') { // 呈现用户列表页面 if (pathname == '/list') { // 查询用户信息 let users = await User.find(); // html字符串 let list = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h6> <a href="/add" class="btn btn-primary">添加用户</a> </h6> <table class="table table-striped table-bordered"> <tr> <td>用户名</td> <td>年龄</td> <td>爱好</td> <td>邮箱</td> <td>操作</td> </tr> `; // 对数据进行循环操作 users.forEach(item => { list += ` <tr> <td>${ item.name}</td> <td>${ item.age}</td> <td> `; item.hobbies.forEach(item => { list += `<span>${ item}</span>`; }) list += `</td> <td>${ item.email}</td> <td> <a href="/remove?id=${ item._id}" class="btn btn-danger btn-xs">删除</a> <a href="/modify?id=${ item._id}" class="btn btn-success btn-xs">修改</a> </td> </tr>`; }); list += ` </table> </div> </body> </html> `; res.end(list); } [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center]: /images/20221119/e1c8fb6f14fb46b0ba4dcbc8a389e5e8.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 1]: /images/20221119/5c3391da3c2d4f14a19e3c288cb283df.png [20210126132851450.png_pic_center]: /images/20221119/9141260f9b934319965b2e24a844630a.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 2]: /images/20221119/1981549afbc64d20babe38e03ea23bbc.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 3]: /images/20221119/d02e588db7124abb92324b2b12969eb6.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 4]: /images/20221119/0561322db5604caaaf228e2a2de716cd.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 5]: /images/20221119/6cef88e8420c4e5eb783fcf77c3490cc.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 6]: /images/20221119/273f9641086a4ee6be7fe73d9ba5a163.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 7]: /images/20221119/9a2d4101ee6a4c5e92cbf8fae4c4c2cf.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 8]: /images/20221119/8d4e1b8e8f1d45219c49191c0f2010be.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 9]: /images/20221119/e406e746fc9b4ea1a518025533d7f010.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 10]: /images/20221119/7d2328900c174cdea2bd7c5f0aa64eaa.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 11]: /images/20221119/fb265205549d4cd2a579ef051878ab46.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 12]: /images/20221119/7d5a17d9b31643c48d14bd2d9ea427d5.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 13]: /images/20221119/d8275f9a5ca940a48a123544b39ca018.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 14]: /images/20221119/76d1a647843e4ed0adeec63af3579206.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3A0NDUwOTgzNTU_size_16_color_FFFFFF_t_70_pic_center 15]: /images/20221119/2ed954d9be7c413ba5b179635619c363.png
还没有评论,来说两句吧...