目录
1、数据库概述及环境搭建
为什么使用数据库?
- 因为动态网站的数据都是存储在数据库里
- 数据库可以用来持久存储客户端通过表单收集的用户信息
- 数据库本身可以对数据进行高效的管理
什么是数据库?
存储数据的仓库,时独立于语言之外的软件,可以通过API来操作它
数据库相关概念
一个数据库软件可以包含多个数据仓库,每个数据仓库中包含多个数据集合,每个数据集合里包含多条文档(具体数据)
mongoose第三方模块
- 使用node.js操作mongoDB数据库需要依赖node.js第三方包mongoose
- 使用 npm install mongoose
启动mongoDB
- 在命令行工具中运行 net start mongoDB 即可启动mongoDB,否则无法连接
- 停止运行 net stop mongoDB
数据库连接
使用mongoose提供的connect方法即可连接数据库(第三模块记得引入)
mongoose.connect('mongodb://localhost/playground')
//协议 地址 数据库的名称
.then(()=>console.log('数据库连接成功'))
.catch(err=>console.log('数据库连接失败',err));
开启成功会提示缺少条件
在content方法里添加第二个参数
const mongoose= require('mongoose');
mongoose.connect('mongodb://localhost/playground',{ useNewUrlParser: true, useUnifiedTopology: true})
.then(()=>console.log('数据库开启成功'))
.catch(err=>console.log(err,'开启失败'))
开启成功
创建数据库
在mongodb中不需要显式创建数据库,如果正在使用的数据库不存在,会自动创建
创建集合
分为两步,一是对集合设定规则,二是创建集合,创建mongoose.Schema构造函数的实例即可创建集合
集合名称的首字母应该大写
.model()方法第一个参数是名称,第二个是集合规则
创建文档1
创建文档实际上就是向集合中插入数据
- 创建集合实例
- 调用实例对象下的save方法将数据保存到数据库中
const mongoose= require('mongoose');
const { stringify } = require('querystring');
mongoose.connect('mongodb://localhost/playground',{ useNewUrlParser: true, useUnifiedTopology: true})
.then(()=>console.log('数据库开启成功'))
.catch(err=>console.log(err,'开启失败'))
//创建集合规则
const courseSchema = new mongoose.Schema({
name:String, //首字母要大写
author:String,
inPnblished:Boolean
})
//使用规则去创建集合
const Course= mongoose.model('Course',courseSchema)//.model()方法第一个参数是名称,第二个是集合规则
//创建文档
const course= new Course({ //注意Course是集合,course是文档
name:'node.js',
aythor:'terry',
inPnblished:true
});
//保存文档
course.save();
创建文档2
create也返回promise,可以用.then、.catch去调用
const mongoose= require('mongoose');
const { stringify } = require('querystring');
mongoose.connect('mongodb://localhost/playground',{ useNewUrlParser: true, useUnifiedTopology: true})
.then(()=>console.log('数据库开启成功'))
.catch(err=>console.log(err,'开启失败'))
const courseSchema = new mongoose.Schema({
name:String,
author:String,
inPnblished:Boolean
})
const Course= mongoose.model('Course',courseSchema)
Course.create({name:'javascropt',author:'黑马程序员',inPnblished:false},(err,result)=>{
console.log(err);
console.log(result);
})
2、mongodb增删改查操作
导入数据
mongoimport -d 数据库名称 -c 合集名称 -file 要导入的文件
查询文档
const mongoose= require('mongoose');
const { stringify } = require('querystring');
mongoose.connect('mongodb://localhost/playground',{ useNewUrlParser: true, useUnifiedTopology: true})
.then(()=>console.log('数据库开启成功'))
.catch(err=>console.log(err,'开启失败'))
const userSchema = new mongoose.Schema({
name:String,
age:Number,
email:String,
password:String,
hobbies:[String]
})
const User= mongoose.model('User',userSchema)
User.find().then(result=>console.log(result))
.find()
User.find({_id: 'id名'}).then(result=>console.log(result))
里面也可以添加条件
User.find({age:{$gt:20,$lt:50}}).then(result=>console.log(result))
$gt是大于,$lt是小于
User.find({hobbies:{$in:['足球']}}).then(result=>console.log)
查询爱好是足球的合集,$in是包含
User.find().select('name email -_id').then(result=>console.log(result))
.select()选择要查询的字段,如果不想查询某字段就在前加_
User.find().sort('age').then(result=>console.log(result))
升序排列
User.find().skip(2).limit(2).then(result=>console.log(result))
skip跳过多少条数据,limit限制查询数量
.findOne()
也能查找文档 (也能传入查找条件)返回的是对象
User.findOne().then(result=>console.log(result))
返回一条文档,默认返回当前集合中的第一条文档
删除文档
删除单个
后可以接条件,如果条满足多条数据,那就删除第一条,返回你删除的哪一条
Course.findOneAndDelete({}).then(result=>console.log(result))
删除多个
如果后不接条件就删除整个集合,会返回一个对象{n:4,ok:1},n代表删除4条,ok代表操作成功
Course.deleteMany({}).then(result=>console.log(result))
更新文档(修改)
更新单个
User.updateOne({等修改的值},{要修改的值}).then(result=>console.log(result))
更新多个
User.updateMany({等修改的值},{要修改的值}).then(result=>console.log(result))
mongoose验证
在创建集合规则,可以设置当前字段的验证规则,验证失败就插入失败
- required:ture 必传字段(如果是必传字段,插入内容缺失会报错)
-
const userSchema = new mongoose.Schema({ title:{ type:string, required:[ture,'请传入文章标题'] //数组格式可以定义报错信息 } });
- minlength:2 最小字符串长度
- maxlength:5 最大字符串长度 (都可以自定义报错信息)
-
const userSchema = new mongoose.Schema({ title:{ type:string, required:[ture,'请传入文章标题'] //数组格式可以定义报错信息 minlength:[2,'最小字符串长度'] maxlength:[5,'最大字符串长度'] } });
- trim:ture 去除字符串两端空格
- min: max: 最大最小的字段
-
const userSchema = new mongoose.Schema({ title:{ type:string, required:[ture,'请传入文章标题'] //数组格式可以定义报错信息 minlength:[2,'最小字符串长度'] maxlength:[5,'最大字符串长度'] }, age:{ type:Number, min:18, max:100 } });
- default: 默认
-
publishDate:{ //发布日期 type:Date, //时间类型 default:Date.now //传了就用,没传就是now }
- enum:枚举、列举
-
publishDate:{ type:String, enum:['html','css','nodejs'] //规定上传范围,html只是代号不代表真正的文件格式 }
- validata:{}:函数验证、message:自定义错误信息
获取插入文档的错误信息
const Post=mongoose.model('Post',postSchema);
Post.create({title:"aa",age:60,category:'java',author:'bd'})
.then(result=>{
//获取错误信息
const err =error.errors;
//循环错误信息对象
for(var attar in err){
console.log(err[attr]['message']);
}
})
3.集合关联
通常不同的集合的数据之间是有关系的,例如文章信息和用户信息存储在不同的集合中,但是文章是某个用户发表的,要查询文章的所有信息包括发表用户,就需要用到集合关联
- 使用id对集合进行关联
- 使用populate方法进行关联集合查询
代码实现:
通过populate()
函数,使你可以在一个文档中引用另一个集合中的文档,并将其填充到指定文档路径中。
增删改查综合案例
p15~p21
模板引擎
- 模板引擎是第三方模块
- 让开发者以更加友好的方式拼接字符串,是项目代码更加清晰、易于维护
art-template 模板引擎
- 在命令行工具中使用 npm insatll art-template 命令进行下载
- 使用 const template =require('art-template') 引入模板引擎
- 告诉模板引擎要拼接的数据和模板在哪 const html = template('模板路径',数据);
-
右边是index.art
-
使用绝对路径更好
模板语法
- art-template同时支持两种模板语法:标准语法和原始语法
- 标准语法可以让模板更加容易读写,原始语法具有更加强大的逻辑处理能力
- 标准语法:{{数据}}
- 原始语法:<%=数据 %>
输出语法:
原文输出
如果数据中携带HTML标签,默认模板引擎不会解析标签,会将其转义后输出
- 标准语法:{{@数据}}
- 原始语法:<%-数据 %>
条件判断
在模板中可以根据条件来决定显示哪块HTML代码
- 标准语法:{{ if条件 }} {{ /if }}
- {{ if v1 }} {{ else if v2 }} {{ /if }}
-
{{if age >18}} 年龄大于18 {{else if age <15}} 年龄小于15 {{ /if}
- 原始语法:<% if (value) { %>.......<% } %> //可以写所有的原生js代码
- <% if (v1) { %>.......<% } else if (v2) { %>......<%} %>
<% if (age >18) { %>
年龄大于18
<% } else if (age < 15) { %>
年龄小于15
<% } else { %>
年龄不符合要求
<% } %>
循环
- 标准语法:{{each 数据}} {{/each}}
- 原始语法:<% for() {%> <%} %>
target就是你要循环的数据集合的名称
子模版
- 可以将网站的公共区域抽离到单独的文件中
- 标准语法:{{include '模板'}}
- 原始语法:< % include('模板') % >
模板继承
可以将HTML骨架抽离到单独的文件中,其他模板也可以继承骨架,因为子模版不包含骨架
案例:
{{block}} {{/block}} :预留位置
{{extend '. / layout.art ' }} 继承语法后跟要父文件的名字
模板配置
像模版中导入变量 template.defaults.imports.变量名 =变量值;
设置模板根目录 template.defaults.root = 模板目录
设置模板默认后缀 template.defaults.extname = ' .art '
使用:
- npm install dateformat
- var dateFormat = require(' dateformat') //引入模块
在模板文件里引用dateformat方法,后接处理格式
综合案例:
p30~p35