MongoDB数据库

数据库概述及环境搭建

MongoDB数据库下载安装

下载地址:https://www.mongodb.com/download-center/community

MongoDB可视化软件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2vzf0xgL-1587086811691)(https://s2.ax1x.com/2020/02/18/3kzO4H.png)]

数据库相关概念

在一个数据库软件中可以包含多个数据仓库,在每个数据仓库中可以包含多个数据集合,每个数据集合中可以包含多条文档(具体的数据)。

术语解释说明
database数据库,mongoDB数据库软件中可以建立多个数据库
collection集合,一组数据的集合,可以理解为JavaScript中的数组
document文档,一条具体的数据,可以理解为JavaScript中的对象
field字段,文档中的属性名称,可以理解为JavaScript中的对象属性

使用Node.js操作MongoDB数据库需要依赖Node.js第三方包mongoose
使用npm install mongoose命令下载

启动MongoDB

在命令行工具中运行net start mongoDB即可启动MongoDB,否则MongoDB将无法连接。|| net stop mongoDB 暂停

数据库连接

使用mongoose提供的connect方法即可连接数据库。

mongoose.connet('mongodb://localhost/playground')
		.then(()=>console.log('数据库链接成功'))
		.catch((err)=>console.log('数据库链接失败',err));

在MongoDB中不需要显式创建数据库,如果正在使用的数据库不存在,MongoDB会自动创建。

MongoDB增删改查操作

创建集合

创建集合分为两步,一是对集合设定规则,二是创建集合,创建mongoose.Schema构造函数的实例即可创建集合。

//设定集合规则
const courseSchema=new mongoose.Schema({
	name:String,
	author:String,
	isPublished:Boolean
})
// 使用规则创建集合
const Course=mongoose.model('Course',courseSchema);

创建文档

创建文档实际上就是向集合中插入数据。 分为两步:

  • 创建集合实例。
  • 调用实例对象下的save方法将数据保存到数据库中。
//方法一
const course = new Course({
	name: 'Node.js course',
	author: '黑马讲师',
	isPublished:true
})
course.save();

//方法二
Course.create({
    name:'javascript',
    author:'黑马讲师',
    isPublished:false
},(err,doc)=>{
    console.log(err);
    console.log(doc);
})

mongoDB数据库导入数据

mongoimport –d 数据库名称 –c 集合名称 –file 要导入的数据文件
找到mongodb数据库的安装目录,将安装目录下的bin目录放置在环境变量中。

mongoimport -d playground -c users --file ./user.json 

查询文档

//  根据条件查找文档(条件为空则查找所有文档)
Course.find().then(result => console.log(result))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UiOSnjzc-1587086811693)(https://s2.ax1x.com/2020/02/18/3AuaLD.png)]

//  根据条件查找文档
Course.findOne({name: 'node.js基础'}).then(result => console.log(result))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QuyYToKT-1587086811696)(https://s2.ax1x.com/2020/02/18/3AuhwQ.png)]

//  匹配大于 小于
User.find({age: {$gt: 20, $lt: 50}}).then(result => console.log(result))
//  匹配包含
User.find({hobbies: {$in: ['敲代码']}}).then(result => console.log(result))
//  选择要查询的字段  -_id 表示不显示id
User.find().select('name email').then(result => console.log(result)) 
// 将数据按照年龄进行排序 -age 降序
User.find().sort('age').then(result => console.log(result))
//  skip 跳过多少条数据  limit 限制查询数量
User.find().skip(2).limit(2).then(result => console.log(result))

删除文档

// 删除单个
Course.findOneAndDelete({_id: '5csajd'}).then(result => console.log(result))
// 删除多个
User.deleteMany({}).then(result => console.log(result))

更新文档

// 更新单个
User.updateOne({查询条件}, {要修改的值}).then(result => console.log(result))
// 更新多个
User.updateMany({查询条件}, {要更改的值}).then(result => console.log(result))

mongoose验证

在创建集合规则时,可以设置当前字段的验证规则,验证失败就则输入插入失败。

  • required: true 必传字段
  • minlength:3 字符串最小长度
  • maxlength: 20 字符串最大长度
  • min: 2 数值最小为2
  • max: 100 数值最大为100
  • enum: [‘html’, ‘css’, ‘javascript’, ‘node.js’]
  • trim: true 去除字符串两边的空格
  • validate: 自定义验证器
  • default: 默认值

获取错误信息:error.errors[‘字段名称’].message

const postSchema=new mongoose.Schema({
    title:{
        type:String,
        //必选
        required:[true,'请输入文章标题'],
        //字符串最小长度
        minlength:[2,'长度小于2'],
        //字符串最大长度
        maxlength:[5,'长度大于5'],
        // 取消两边的空格
        trim: true
    },
    age:{
        type:Number,
        // 数组最小长度
        min:18,
        max:100
    },
    publishDate:{
        type: Date,
        // 默认值
        default: Date.now
    },
    category:{
        type: String,
        // 可用分类
        enum: {
            values:['html','css','java','nodejs'],
            message: '分类要在范围内'
        }
    },
    author:{
        type:String,
        //自定义验证器
        validate:{
            validator:(v)=>{
                // 返回布尔值
                // true 验证成功
                // false 验证失败
                // v 要验证的值
                return v&&v.length>4
            },
            // 自定义信息
            message:'传入的值不符合要求'
        }
    }
});

集合关联

通常不同集合的数据之间是有关系的,例如文章信息和用户信息存储在不同集合中,但文章是某个用户发表的,要查询文章的所有信息包括发表用户,就需要用到集合关联。

  • 使用id对集合进行关联
  • 使用populate方法进行关联集合查询

3AKO3t.png


const userSchema=new mongoose.Schema({
    name:{
        type:String,
        required:true
    }
});
// 文章集合规律
const postSchema = new mongoose.Schema({
    title:{
        type: String
    },
    author:{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    }
});
const User = mongoose.model('User',userSchema);
const Post = mongoose.model('Post',postSchema);

// 创建用户
User.create({name:'itheima'}).then(result=>console.log(result));
// 创建文章
// Post.create({title: '123',author:'5e4a95f2fe269f36d4ee0036'}).then((a)=>console.log(a))
Post.find().populate('author').then((a)=>console.log(a))

模板引擎artTemplate

模板引擎的基础概念

模板引擎

模板引擎是第三方模块。
让开发者以更加友好的方式拼接字符串,使项目代码更加清晰、更加易于维护。

 // 未使用模板引擎的写法
 var ary = [{ name: '张三', age: 20 }];
 var str = '<ul>';
 for (var i = 0; i < ary.length; i++) { 
    str += '<li>\
        <span>'+ ary[i].name +'</span>\
        <span>'+ ary[i].age +'</span>\
    </li>';
 }
 str += '</ul>'; 
 <!-- 使用模板引擎的写法 --> 
 <ul>
    {{each ary}}
        <li>{{$value.name}}</li>
        <li>{{$value.age}}</li>
    {{/each}}
 </ul>

art-template模板引擎

  1. 在命令行工具中使用 npm install art-template 命令进行下载
  2. 使用const template = require(‘art-template’)引入模板引擎
  3. 告诉模板引擎要拼接的数据和模板在哪 const html = template(‘模板路径’, 数据);
  4. 使用模板语法告诉模板引擎,模板与数据应该如何进行拼接
 // 导入模板引擎模块
 const template = require('art-template');
 // 将特定模板与特定数据进行拼接
 const html = template('./views/index.art',{
    data: {
        name: '张三',
        age: 20
    }
 }); 
 <div>
    <span>{{data.name}}</span>
    <span>{{data.age}}</span>
 </div>

模板引擎的语法

  • art-template同时支持两种模板语法:标准语法和原始语法。
  • 标准语法可以让模板更容易读写,原始语法具有强大的逻辑处理能力。

输出

  <!-- 标准语法 -->
 <h2>{{value}}</h2>
 <h2>{{a ? b : c}}</h2>
 <h2>{{a + b}}</h2>

  <!-- 原始语法 -->
 <h2><%= value %></h2>
 <h2><%= a ? b : c %></h2>
 <h2><%= a + b %></h2>

原文输出

  • 标准语法:{{@ 数据 }}
  • 原始语法:<%-数据 %>
 <!-- 标准语法 -->
 <h2>{{@ value }}</h2>
 <!-- 原始语法 -->
 <h2><%- value %></h2>

条件判断

 <!-- 标准语法 --> 
 {{if 条件}} ... {{/if}}
 {{if v1}} ... {{else if v2}} ... {{/if}}
 <!-- 原始语法 -->
 <% if (value) { %> ... <% } %>
 <% if (v1) { %> ... <% } else if (v2) { %> ... <% } %>

循环

  • 标准语法:{{each 数据}} {{/each}}
  • 原始语法:<% for() { %> <% } %>
 <!-- 标准语法 -->
 {{each target}}
     {{$index}} {{$value}}
 {{/each}}
  <!-- 原始语法 -->
 <% for(var i = 0; i < target.length; i++){ %>
     <%= i %> <%= target[i] %>
 <% } %>

子模版

  • 标准语法:{{include ‘模板’}}
  • 原始语法:<%include(‘模板’) %>
  <!-- 标准语法 -->
 {{include './header.art'}}
  <!-- 原始语法 -->
 <% include('./header.art') %>

模板继承

3AQFde.png

 <!doctype html>
 // layout.art
 <html>
     <head>
         <meta charset="utf-8">
         <title>HTML骨架模板</title>
         {{block 'head'}}{{/block}}
     </head>
     <body>
         {{block 'content'}}{{/block}}
     </body>
 </html>
 <!--index.art 首页模板-->
 {{extend './layout.art'}}
 {{block 'head'}} <link rel="stylesheet" href="custom.css"> {{/block}}
 {{block 'content'}} <p>This is just an awesome page.</p> {{/block}}

模板配置

设置模板根目录 template.defaults.root = 模板目录
向模板中导入变量 template.defaults.imports.变量名 = 变量值;
设置模板默认后缀 template.defaults.extname = '.art'

第三方模块 router

功能:实现路由
步骤:

  1. 获取路由对象
  2. 调用路由对象提供的方法创建路由
  3. 启用路由,使路由生效
const http=require('http');
const getRouter = require('router')
const router = getRouter();
const server=http.createServer();
router.get('/add', (req, res) => {
    res.end('Hello World!')
})
server.on('request', (req, res) => {
    router(req, res)
})
server.listen(3000);

第三方模块 serve-static

功能:实现静态资源访问服务
步骤:

  1. 引入serve-static模块获取创建静态资源服务功能的方法
  2. 调用方法创建静态资源服务并指定静态资源服务目录
  3. 启用静态资源服务功能
const http=require('http');
const server=http.createServer();
const serveStatic = require('serve-static')
const serve = serveStatic('public')
server.on('request', () => { 
    serve(req, res)
})
server.listen(3000)

案例部分代码:

//app.js 入口
const http=require('http');
const template=require('art-template');
const path=require('path');
const router=require('./route/index');
// 引入静态资源访问模块
const serveStatic=require('serve-static');
// 引入处理日期的第三方模块
const dateformat=require('dateformat');
const serve=serveStatic(path.join(__dirname,'public'));
template.defaults.root=path.join(__dirname,'views');
// 模板函数传入参数
template.defaults.imports.dateformat=dateformat;
//数据库链接
require('./model/connect');
const app=http.createServer();
app.on('request',(req,res)=>{
    // 启动路由功能
    router(req,res,()=>{});
    // 启用静态资源访问服务功能
    serve(req,res,()=>{});
});
app.listen(80);
console.log('成功');
//引入router模块
const getRouter=require('router');
//获取路由对象
const router=getRouter();
//学生信息集合 数据库
const Student=require('../model/user');
//引用模板引擎
const template=require('art-template');
//映入querysting模块 将表达传过来的东西转成对象形式
const querystring=require('querystring');

//呈现学生档案信息页面
router.get('/add',(req,res)=>{
    let html=template('index.art',{});
    res.end(html);
});

//呈现学生档案列表信息列表页面
router.get('/list',async (req,res)=>{
    //查询学生信息
    let students=await Student.find();
    // console.log(students);
    let html=template('list.art',{
        students:students
    });
    res.end(html);
})
router.post('/add',(req,res)=>{
    //接受post请求参数
    let formData='';
    req.on('data',param=>{
        formData+=param;
    })
    req.on('end',async ()=>{
        await Student.create(querystring.parse(formData));
        res.writeHead(301,{
            location: '/list'
        });
        res.end();
    })
})
module.exports=router; //把router导出 module.exports.router 那么接受方也需要.router调用 否则传入的是对象

如何解决端口被占用

netstat -ano|findstr “3010” // 3010是查询你的端口号
taskkill -pid 4488 -f // 4488是查询出来的相应的最后那个数字
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值