文件操作
// 1. 导入fs模块
const fs = require('fs')
文件写入
//异步写入
// fs.writeFile(文件名, 待写入的数据, 选项设置(可选), 回调函数)
fs.writeFile('./座右铭.txt', '三人行,必有我师傅', err => {
//如果写入失败,err就是一个错误对象, 写入成功 err:null
if (err) {
console.log('写入失败');
} else {
console.log('写入成功');
}
})
//同步写入
// fs.writeFileSync(文件名, 待写入的数据)
fs.writeFileSync('./data.txt', 'test');
文件追加
// 调用 appendFile
fs.appendFile('./座右铭.txt', '择其善者而从之,则其不善者而改之', err => {
//判断
// 如果写入失败,err就是一个错误对象, 写入成功 err: null
if (err) {
console.log('追加失败');
} else {
console.log('追加成功');
}
})
fs.appendFileSync('./座右铭.txt', '温故而知新,可以为师傅');
\r\n 换行
//writeFile 实现追加写入
fs.writeFile('./座右铭.txt', '\r\nlove love love', { flag: 'a' }, err => {
if (err) {
console.log('追加失败');
} else {
console.log('追加成功');
}
})
文件读取
//1. 异步读取 readFile
fs.readFile('./静夜思.txt', (err, data) => {
if (err) {
console.log('读取失败');
} else {
console.log(data.toString());
}
})
//2.同步读取 readFileSync
let data = fs.readFileSync('./静夜思.txt');
console.log(data.toString());
文件复制
// 方式一: readFile
//读取文件内容
let data = fs.readFileSync('./data.txt')
//把读取到的文件内容,再写入到新文件中
// //写入文件
fs.writeFileSync('./newData.txt', data)
//方式二 流式操作
//创建读取流对象
const rs = fs.createReadStream('./data.txt')
//创建写入流对象
const ws = fs.createWriteStream('./newData.txt')
//绑定data事件
rs.on('data', chunk => {
ws.write(chunk)
})
文件重命名
//调用rename方法
fs.rename('./oldName.txt', './newName.txt', err => {
if (err) {
console.log('操作失败');
} else {
console.log('操作成功');
}
})
文件删除
//调用 unlink 方法
fs.unlink('../练习/newData.txt', err => {
if (err) {
console.log('操作失败');
} else {
console.log('操作成功');
}
})
//调用rm方法
fs.rm('./论语.txt', err => {
if (err) {
console.log('操作失败');
} else {
console.log('操作成功');
}
})
创建文件夹
// 创建文件夹 mk-make dir-directory
fs.mkdir('./文件', err => {
if (err) {
console.log('操作失败');
} else {
console.log('操作成功');
}
})
//2-2递归创建
fs.mkdir('./文件/a/b/c', { recursive: true }, err => {
if (err) {
console.log('操作失败');
} else {
console.log('操作成功');
}
})
文件夹读取
const fs = require('fs')
//读取文件夹
fs.readdir('../a/b', (err, data) => {
if (err) {
console.log('操作失败');
} else {
console.log(data);
}
})
删除文件夹
//建议使用
fs.rm('./文件', { recursive: true }, err => {
if (err) {
console.log('操作失败');
} else {
console.log('操作成功');
}
})
Path路径
//导入path模块
const path = require('path')
path.basename
//获取路径的基本名称
let str = 'E:\\nodeJs\\0722-NodeJs\\code\\parse.js'
console.log(path.basename(str));//输出parse.js
path.dirname
//dirname 获取路径的目录名
let str = 'E:\\nodeJs\\0722-NodeJs\\code\\parse.js'
console.log(path.dirname(str));//E:\nodeJs\0722-NodeJs\code
path.extname
//获取路径的扩展名
let str = 'E:\\nodeJs\\0722-NodeJs\\code\\parse.js'
console.log(path.extname(str));//.js 获取扩展名.js
console.log(typeof(path.extname(str)));//string //扩展名的类型是字符串类型
console.log(path.extname(str).slice(1)) //js
path.parse
//path.parse() 方法返回一个对象,其属性表示 path 的重要元素。
//E:\nodeJs\0722-NodeJs\code\parse.js
let str = 'E:\\nodeJs\\0722-NodeJs\\code\\parse.js'
console.log(path.parse(str));
//输出
/**
* {
root: 'E:\\', 文件所在盘符
dir: 'E:\\nodeJs\\0722-NodeJs\\code', 文件夹路径
base: 'parse.js', 文件名
ext: '.js', 文件扩展名
name: 'parse' 文件的文件名
}
*/
console.log(path.parse(str).dir);
//输出 :E:\nodeJs\0722-NodeJs\code
path.resolve
//path.resolve() 方法将路径或路径片段的序列解析为绝对路径。
path.resolve('/foo/bar', './baz');
// Returns: '/foo/bar/baz'
path.resolve('/foo/bar', '/tmp/file/');
// Returns: '/tmp/file'
path.sep
//获取操作系统的路径分隔符
// sep
const fs = require('fs')
const path = require('path')
console.log(path.sep);
// window \
//linux /
'foo/bar/baz'.split(path.sep);
// Returns: ['foo', 'bar', 'baz']
'foo\\bar\\baz'.split(path.sep);
// Returns: ['foo', 'bar', 'baz']
__filename 获取文件的绝对路径
Http模块
//导入http模块
const http = require('http')
创建http服务
//创建服务对象
// const server = http.createServer(function (request, response) { })
const server = http.createServer((request, response) => {
// request 请求报文的封装对象 获取报文里面的相关内容(请求行,头,体)
// response 响应报文的封装
response.setHeader('content-type','text/html;charset=utf-8');//中文乱码问题
response.end('hello http server')//设置响应体
})
//监听端口,启动服务
server.listen(9000, () => {
console.log('服务启动成功');
})
提取http报文
const server = http.createServer((request, response) => {
//获取请求方法
console.log(request.method);
//获取请求的url
console.log(request.url);
//获取http协议的版本号
console.log(request.httpVersion);
//获取http的请求头
console.log(request.headers);
response.setHeader('content-type','text/html;charset=utf-8');//中文乱码问题
response.end('hello, world')
})
//监听端口,启动服务
server.listen(9000, () => {
console.log('服务启动成功');
})
提取http报文的请求体
const http = require('http');
const server = http.createServer((req, res) => {
if (req.method === 'POST') {
let body = '';
// 监听数据块
req.on('data', chunk => {
body += chunk.toString(); // 将接收到的Buffer转换为字符串
});
// 数据接收完毕
req.on('end', () => {
console.log(body); // 这里就是请求体
// 处理请求体(例如解析JSON)
try {
const parsedBody = JSON.parse(body);
console.log(parsedBody); // 假设请求体是JSON格式
// 发送响应
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('请求体已接收并解析');
} catch (e) {
// 处理解析错误
res.writeHead(400, {'Content-Type': 'text/plain'});
res.end('请求体解析错误');
}
});
} else {
// 对于非POST请求,发送一个简单的响应
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('只接受POST请求');
}
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}/`);
});
提取http报文的中URL路径与查询字符串
//方法一
const http = require('http')
// 导入url模块
const url = require('url')
//创建服务对象
const server = http.createServer((request, response) => {
// 解析request.url
let res = url.parse(request.url, true)
console.log(res);
//输出
/*
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?a=100&b=500',
query: [Object: null prototype] { a: '100', b: '500' },
pathname: '/search', ****URL路径
path: '/search?a=100&b=500',****查询字符串
href: '/search?a=100&b=500'
}
*/
//路径
let pathname = res.pathname
console.log(pathname); // /search
//查询字符串
let keyword = res.query.keyword
console.log(keyword); ///search?a=100&b=500
response.end('url') //浏览器响应内容
})
//监听端口,启动服务
server.listen(9000, () => {
console.log('服务启动成功');
})
//方法二
const http = require('http')
//创建服务对象
const server = http.createServer((request, response) => {
//实例化 url对象
// let url = new URL('http://www.xxx.com/search?a=100&b=500')
//let url = new URL(request.url, 'http://127.0.0.1')
let url = new URL('/search?a=100&b=500', 'http://127.0.0.1')
// 输出路径
console.log(url);
console.log(url.pathname);
// 输出keyword 查询字符串
console.log(url.searchParams.get('keyword'));
response.end('url new')
})
//监听端口,启动服务
server.listen(9000, () => {
console.log('服务启动成功');
})
设置http响应报文
const http = require('http')
//创建服务对象
const server = http.createServer((request, response) => {
//1.设置响应状态码
response.statusCode = 200;
//2.响应状态的描述
response.statusMessage = 'iloveyou'
//3.响应头
response.setHeader('content-type','text/html;charset=utf-8');
response.setHeader('myHeader', 'test test test')
//设置多个同名的响应头
response.setHeader('text', ['a','b','c'])
//response.end('hello http')//设置响应体
// 4.响应体设置
response.write('love')
response.write('love')
response.write('love')
response.write('love')
response.end()
// end方法只能有一个
})
//监听端口,启动服务
server.listen(9000, () => {
console.log('服务启动成功');
})
/*响应报文
HTTP/1.1 200 iloveyou
content-type: text/html;charset=utf-8
myHeader: test test test
text: a
text: b
text: c
Date: Sat, 07 Sep 2024 02:39:40 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked
*/
EJS模板引擎
安装
$ npm install ejs
用法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>我爱你<%= china %></h2>
<%= weather %>
</body>
</html>
//安装EJS
//导入ejs
const ejs = require('ejs')
const fs = require('fs')
//字符串
let china = '中国'
let weather = 'sunny'
// let str = `我爱你${china}`
// console.log(str);
//使用ejsx渲染
// let str = '我爱你<%= china %>'
let str = fs.readFileSync('./index.html').toString();
let result = ejs.render(str, { china: china, weather:weather })
console.log(result);
在Express中使用ejs.js
/*homne.ejs文件*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2><%= title %></h2>
</body>
</html>
//导入express
const express = require('express')
const path = require('path')
//创建应用对象
const app = express()
//设置模板引擎
app.set('view engine', 'ejs')
//设置模板文件存放位置
//模板文件:具有模块文件内容的文件
app.set('views', path.resolve(__dirname , './views'))
/*app.set(name, value):这是Express应用实例的一个方法,用于设置应用的设置项。这个方法接受两个参数:name(设置项的名称)和value(设置项的值)。在这个例子中,我们设置的是与视图(views)相关的设置项。*/
//创建一个路由
app.get('/home', (req, res) => {
// res.render('模板的文件名', '数据')
let title = 'iloveyou'
res.render('home',{title})
})
app.listen(3000, () => {
console.log('服务启动');
})
generator工具
安装
npm install -g express-generator
express -e generator
lowdb
安装
npm i lowdb@1.0.0
https://www.npmjs.com/package/lowdb/v/1.0.0
用法
//导入lowdb
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')
const adapter = new FileSync('db.json')
//获取db对象
const db = low(adapter)
// 初始化数据
// db.defaults({ posts: [], user: {} }).write()
//node .\lowdb.js
//写入数据
// db.get('posts').push({ id: 1, title: "good" }).write()
// db.get('posts').push({ id: 2, title: "day" }).write()
// db.get('posts').unshift({ id: 0, title: "hello" }).write()
//获取数据
console.log(db.get('posts').value());
// [
// { id: 0, title: 'hello' },
// { id: 1, title: 'good' },
// { id: 2, title: 'day' }
// ]
//删除数据
// db.get('posts').remove({ id: 0 }).write();
// let result = db.get('posts').remove({ id: 0 }).write();
// console.log(result);//[ { id: 0, title: 'hello' } ]
//获取单条数据
let res = db.get('posts').find({ id: 1 }).value()
console.log(res);//{ id: 1, title: 'good' }
// 更新数据
db.get('posts').find({ id: 1 }).assign({ title: "morning" }).write()
console.log(db.get('posts').value());
//[ { id: 1, title: 'morning' }, { id: 2, title: 'day' } ]
初始化db对象生成db.json文件
{
"posts": [
{
"id": 1,
"title": "morning"
},
{
"id": 2,
"title": "day"
}
],
"user": {}
}
NodeJs-express框架
安装
//express 本身是一个 npm 包,所以可以通过 npm 安装
npm init
npm i express
express初体验
//导入express
const express = require('express')
//创建应用对象
const app = express()
//创建一个路由
app.get('/home', (req, res) => {
res.end("hello express")
})
//监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000, 正在监听中....');
})
express路由
//导入express
const express = require('express')
//创建应用对象
const app = express()
//创建一个路由
app.get('/home', (req, res) => {
res.end("hello express")
})
app.get('/', (req, res) => {
res.end("home")//每个网站的首页都是这个路由负责响应的
})
app.post('/login', (req, res) => {
res.end("login")//每个网站的首页都是这个路由负责响应的
})
//匹配所有的方法
app.all('/test', (req, res) => {
res.end("test test")
})
//404响应
app.all('*', (req, res) => {
res.end("404 Not Found")
})
//监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000, 正在监听中....');
})
获取请求的参数
//导入express
const express = require('express')
//创建应用对象
const app = express()
//创建一个路由
app.get('/request', (req, res) => {
// 原生的操作
//获取请求的方法
console.log(req.method);
//获取请求的路径
console.log(req.url);
//获取请求的版本号
console.log(req.httpVersion);
//获取请求头
console.log(req.headers);
//express 操作
console.log(req.path);
console.log(req.query);//获取查询字符串
//获取ip
console.log(req.ip);
//获取指定的请求头
console.log(req.get('host'));
res.end("hello express")
})
//监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000, 正在监听中....');
})
req.query查询字符串
const express = require('express');
const app = express();
app.get('/search', (req, res) => {
// 假设请求的URL是 /search?q=nodejs&page=2
// req.query 将是一个对象,包含 { q: 'nodejs', page: '2' }
// 访问查询参数
const searchQuery = req.query.q;
const page = req.query.page;
// 使用查询参数做一些处理
console.log(`Searching for: ${searchQuery} on page ${page}`);
// 返回一个响应
res.send(`Searching for ${searchQuery} on page ${page}`);
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
获取路由参数
//导入express
const express = require('express')
//创建应用对象
const app = express()
app.get('/:id.html', (req, res) => {
// 获取路由url参数
console.log(req.params.id);
res.setHeader('content-type', 'text/html;charset=utf-8')
res.end("商品详情")
})
//监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000, 正在监听中....');
})
id
是一个路由参数(也称为动态段或捕获组),它允许URL中包含一个动态的部分,这个部分的值可以在请求处理函数(即回调函数)中通过req.params.id
访问。
express设置响应
//导入express
const express = require('express')
//创建应用对象
const app = express()
//获取请求的路由规则
app.get("/response", (req, res) => {
//1. express 中设置响应的方式兼容 HTTP 模块的方式
res.statusCode = 404;
res.statusMessage = 'xxx';
res.setHeader('abc','xyz');
res.write('响应体');
res.end('xxx');
//2. express 的响应方法
res.status(500); //设置响应状态码
res.set('xxx','yyy');//设置响应头
res.send('中文响应不乱码');//设置响应体
//连贯操作
res.status(404).set('xxx','yyy').send('你好朋友')
//3. 其他响应
res.redirect('http://atguigu.com')//重定向
res.download('./package.json');//下载响应
res.json();//响应 JSON
res.sendFile(__dirname + '/home.html') //响应文件内容
});
//监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000, 正在监听中....');
})
express 中间件
中间件函数 可以像路由回调一样访问 请求对象(request) , 响应对象(response)
中间件的作用 就是 使用函数封装公共操作,简化代码
全局中间件
每一个请求 到达服务端之后 都会执行全局中间件函数
/**
*
* 记录每个请求的url和IP地址
*
*
*/
//导入express
const express = require('express')
//导入fs
const fs = require('fs')
//导入path
const path = require('path')
//创建应用对象
const app = express()
//声明中间件函数
function recordMiddleware(req, res, next) {
//解构
let { url, ip } = req
// console.log(url, ip);
//将信息保存在文件中 access.log
fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url} ${ip}\r\n`)
//调用next
next()
}
//使用中间件函数
app.use(recordMiddleware)
//创建路由
app.get('/home', (req, res) => {
res.send('前台首页')
//代码重复
// let { url, ip } = req
// fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url} ${ip}`)
//将重复的代码添加到中间件,可以减少重复代码的使用
})
app.get('/admin', (req, res) => {
res.send('后台首页')
//代码重复
// let { url, ip } = req
// fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url} ${ip}`)
})
app.all('*', (req, res) => {
res.send('404 Not Found')
})
//监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000, 正在监听中....');
})
路由中间件
如果 只需要对某一些路由进行功能封装 ,则就需要路由中间件
/**
* 针对 /admin /setting 的请求,要求URL 携带 code = 521参数,如未携带提示暗号(暗号错误)
*/
//导入express
const express = require('express')
//创建应用对象
const app = express()
//创建路由
// 前台
app.get('/home', (req, res) => {
res.send('前台首页')
})
//声明中间件
let checkCodeMiddleware = (req, res, next) => {
//判断 URL 中是否code参数等于521
if (req.query.code === '521') {
next()
} else {
res.send('暗号错误')
}
}
// 后台
app.get('/admin', checkCodeMiddleware, (req, res) => {
res.send('后台首页')
})
//后台设置
app.get('/setting', checkCodeMiddleware, (req, res) => {
res.send('设置页面')
})
app.all('*', (req, res) => {
res.send('404 Not Found')
})
//监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000, 正在监听中....');
})
获取请求体数据 body-parser
安装
npm i body-parser
中间件函数
//处理 querystring 格式的请求体
let urlParser = bodyParser.urlencoded({extended:false}));
//处理 JSON 格式的请求体
let jsonParser = bodyParser.json();
用法
*****form.html*****
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 表单资源 -->
<h2>用户登录</h2>
<hr>
<form action="http://127.0.0.1:3000/login" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password" id=""><br>
<input type="submit" value="提交">
</form>
<h2></h2>
<img src="" alt="">
</body>
</html>
/**
* 按照要求搭建 HTTP服务
*
*
* GET /login 显示表单网页
* POST /login 获取表单中的用用户名和密码
*
*/
//导入express
const express = require('express');
//获取中间件函数
//express 可以使用 body-parser 包处理请求体
//导入bodyParser
const bodyParser = require('body-parser');
//创建应用对象
const app = express();
// 解析querystring 格式请求体的中间件
const urlencodedParser = bodyParser.urlencoded({ extended: false });
//创建路由
app.get('/login', (req, res) => {
// res.send('表单页面')
//响应html内容
res.sendFile(__dirname + '/11-form.html')
})
app.post('/login',urlencodedParser, (req, res) => {
res.send("获取用户的数据")
//获取用户名和密码
//body-parser
console.log(req.body);//[Object: null prototype] { username: '2023120957', password: '123456' }
})
//监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000, 正在监听中....');
})
路由模块化
对路由进行模块化,更好的管理路由
**创建独立的js文件1, homeRouter
// 写代码
const express = require('express');
//创建路由对象
const router = express.Router();
//创建路由规则
router.get('/home', (req, res) => {
res.send('前台首页')
})
router.get('/search', (req, res) => {
res.send('内容搜索')
})
//暴露router
module.exports = router
**创建独立的js文件2, adminRouter
// 写代码
const express = require('express');
//创建路由对象
const router = express.Router();
//创建路由规则
router.get('/admin', (req, res) => {
res.send('后台首页')
})
//后台设置
router.get('/setting', (req, res) => {
res.send('设置页面')
})
//暴露router
module.exports = router
**主文件
//导入express
const express = require('express')
//引入子路由文件
const homeRouter = require('./routes/homeRouter.js')
const adminRouter = require('./routes/adminRouter.js')
//创建应用对象
const app = express()
//设置和使用中间件
app.use(homeRouter)
app.use(adminRouter)
app.all('*', (req, res) => {
res.send('404 Not Found')
})
//监听端口,启动服务
app.listen(3000, () => {
console.log('服务已经启动,端口3000, 正在监听中....');
})
EJS 模板引擎
安装
npm install ejs
初体验
***01-index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- ejs模板 -->
<h2>我爱你<%= china %></h2>
<%= weather %>
</body>
</html>
***主文件
//导入ejs
const ejs = require('ejs')
//导入 fs
const fs = require('fs')
//字符串
let china = '中国'
let weather = 'sunny'
//使用ejs渲染
// let str = '我爱你<%= china %>'
let str = fs.readFileSync('./01-index.html').toString();
let result = ejs.render(str, { china: china, weather:weather })
console.log(result);
**运行
列表渲染
***02-index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<% people.forEach(item=> { %>
<li>
<%= item %>
</li>
<% }) %>
</ul>
</body>
</html>
***主文件
//导入ejs
const ejs = require('ejs')
const fs = require('fs')
const people= ['张三', '李四', '王二麻子'];
//直接渲染
// let result = ejs.render(`
// <ul>
// <% people.forEach(item => {%>
// <li><%= item %></li>
// <% }) %>
// </ul>`,{people:people})
let str = fs.readFileSync('./02-index.html').toString()
let result = ejs.render(str,{people:people})
console.log(result);
***运行
条件渲染
***03-index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<header>
<% if(islogin){ %>
<span>欢迎回来</span>
<% }else{ %>
<button>登录</button>
<button>注册</button>
<% } %>
</header>
</body>
</html>
***主文件
/**
* 通过islogin 决定输出的内容
*/
//导入ejs
const ejs = require('ejs')
const fs = require('fs')
//变量
let islogin = true;
// let result = ejs.render(`
// <% if(islogin){ %>
// <span>欢迎回来</span>
// <% }else{ %>
// <button>登录</button>
// <button>注册</button>
// <% } %>
// `,{islogin:islogin})
let str = fs.readFileSync('./03-index.html').toString()
let result = ejs.render(str, {islogin:islogin})
console.log(result);
**运行
在express中使用ejs
views文件夹下的home.ejs文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2><%= title %></h2>
</body>
</html>
***主文件夹
//导入express
const express = require('express')
const path = require('path')
//创建应用对象
const app = express()
//1.设置模板引擎
app.set('view engine', 'ejs')
//2.设置模板文件存放位置
//模板文件:具有模块文件内容的文件
app.set('views', path.resolve(__dirname , './views'))
//创建一个路由
app.get('/home', (req, res) => {
// res.render('模板的文件名', '数据')
let title = 'iloveyou'
res.render('home',{title})
})
app.listen(3000, () => {
console.log('服务启动');
})
**运行
mongoDB数据库
简介
MongoDB 是一个基于分布式文件存储的数据库,官方地址 https://www.mongodb.com/
下载安装与启动
下载地址
下载地址: https://www.mongodb.com/try/download/community
配置安装
将压缩包移动到 C:\Program Files 下,然后解压
创建 C:\data\db 目录,mongodb 会将数据默认保存在这个文件夹
以 mongodb 中 bin 目录作为工作目录,启动命令行
运行命令 mongod
mongo 命令连接本机的 mongodb 服务
命令行交互
数据库命令
-
显示所有的数据库
show dbs
-
切换到指定的数据库,如果数据库不存在会自动创建数据库
use 数据库名
-
显示当前所在的数据库
db
-
删除当前数据库
use 库名
db.dropDatabase()
集合命令
1.创建集合
db.createCollection('集合名称')
2.显示当前数据库中的所有集合
show collections
3.删除某个集合
db.集合名.drop()
4.重命名集合
db.集合名.renameCollection('newName')
文档命令
插入文档
db.集合名.insert(文档对象);
查询文档
db.集合名.find(查询条件)
更新文档
db.集合名.update(查询条件,新的文档)
db.集合名.update({name:'张三'},{$set:{age:19}})
删除文档
db.集合名.remove(查询条件)
mongoose
Mongoose 是一个对象文档模型库,官网 http://www.mongoosejs.net/
安装
npm i mongoose
连接数据库
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
console.log("连接成功");
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})
// 关闭mongodb连接
// setTimeout(() => {
// mongoose.disconnect();
// console.log("连接关闭");
// },2000)
创建新文档
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
// console.log("连接成功");
//5.创建文档的结构对象
let BookScheam = new mongoose.Schema({
//设置集合中文档的属性以及属性值的类型
name: String,
author: String,
price: Number
})
//6.创建模型对象, 对文档操作的封装对象
let BookModel = mongoose.model('books', BookScheam)
//7.新增
// Model.create({ /* data */ })
// .then(instance => {
// // 处理实例
// })
// .catch(error => {
// // 处理错误
// });
BookModel.create({
name: '西游记',
author: '吴承恩',
price: 44
}).then(data => {
//如果没有错误,就输出插入后的文档对象
console.log(data);
//8.关闭数据库连接
mongoose.disconnect()
}).catch(error => {
console.log(error);
return;
})
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})
字段类型
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
//5.创建文档的结构对象
let BookScheam = new mongoose.Schema({
//设置集合中文档的属性以及属性值的类型
name: String,
author: String,
price: Number,
is_hot: Boolean,
tags: Array,
pub_time:Date
})
//6.创建模型对象, 对文档操作的封装对象
let BookModel = mongoose.model('books', BookScheam)
//7.新增
BookModel.create({
name: '西游记',
author: '吴承恩',
price: 44,
is_hot: true,
tags: ['猴子', '猪', '人'],
pub_time:new Date()
}).then(data => {
//如果没有错误,就输出插入后的文档对象
console.log(data);
//8.关闭数据库连接
mongoose.disconnect()
}).catch(error => {
console.log(error);
return;
})
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})
字段值验证
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
// console.log("连接成功");
//5.创建文档的结构对象
let BookScheam = new mongoose.Schema({
//设置集合中文档的属性以及属性值的类型
name: {
type: String,
//必填项
required: true,//表明该属性必须不为空
unique:true //设置为独一无二的
},
author: {
type: String,
default:'匿名'//默认值
},
style: {
type: String,
//枚举值
enum :['言情','城市','武侠','志怪']//设置的值必须是数组中的
},
price: Number
})
//6.创建模型对象, 对文档操作的封装对象
let BookModel = mongoose.model('books', BookScheam)
//7.新
BookModel.create({
name :'西游记',
// author: '吴承恩', 如果没有传,就使用默认值
price: 44,
style:'志怪'
}).then(data => {
//如果没有错误,就输出插入后的文档对象
console.log(data);
//8.关闭数据库连接
mongoose.disconnect()
}).catch(error => {
console.log('插入失败');
return;
})
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})
删除文档
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
// console.log("连接成功");
//5.创建文档的结构对象
let BookScheam = new mongoose.Schema({
//设置集合中文档的属性以及属性值的类型
name: String,
author: String,
price: Number,
is_hot: Boolean
})
//6.创建模型对象, 对文档操作的封装对象 mongoose 会使用集合名称复数,创建集合
let BookModel = mongoose.model('novels', BookScheam)
//删除文档数据
//删除一条数据
//模板
// YourModel.deleteOne(conditions)
// .then(result => {
// console.log('文档已删除', result);
// })
// .catch(error => {
// console.error('删除文档时发生错误', error);
// });
//删除id为66a21a5678d38b9257ac6c0e 的一条数据
BookModel.deleteOne({ _id: '66a21a5678d38b9257ac6c0e' })
.then(data => {
console.log('文档已删除', data);
})
.catch(err => {
console.log('文档删除失败');
})
//批量删除
//将is_hot = false 的数据都删除
BookModel.deleteMany({
is_hot :false
})
.then(data => {
console.log('文档已删除', data);
})
.catch(err => {
console.log('文档删除失败');
})
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})
更新文档
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
// console.log("连接成功");
//5.创建文档的结构对象
let BookScheam = new mongoose.Schema({
//设置集合中文档的属性以及属性值的类型
name: String,
author: String,
price: Number,
is_hot: Boolean
})
//6.创建模型对象, 对文档操作的封装对象
let BookModel = mongoose.model('books', BookScheam)
//7.更新文档,更新一条
//将红楼梦的价格 更新为 1000
// BookModel.updateOne({ name: '红楼梦' }, { price: 1000 })
// .then(data => {
// console.log('文档更新成功', data);
// })
// .catch(err => {
// if (err) {
// console.log('文档更新失败', err);
// return;
// }
// })
//批量更新
//将余华的 is_hot全部改成 true
BookModel.updateMany({ author: '余华' }, { is_hot:true })
.then(data => {
console.log('文档更新成功', data);
})
.catch(err => {
if (err) {
console.log('文档更新失败', err);
return;
}
})
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})
读取文档
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
// console.log("连接成功");
//5.创建文档的结构对象
let BookScheam = new mongoose.Schema({
//设置集合中文档的属性以及属性值的类型
name: String,
author: String,
price: Number,
is_hot: Boolean
})
//6.创建模型对象, 对文档操作的封装对象
let BookModel = mongoose.model('books', BookScheam)
//读取文档
//读取单条
// BookModel.findOne({ name:'狂飙' })
// .then(data => {
// console.log('文档读取成功', data);
// })
// .catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
// 根据id获取文档
// BookModel.findById('66a223fa43f2891ecfb9ae89')
// .then(data => {
// console.log('文档读取成功', data);
// })
// .catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
// 批量获取
// BookModel.find({author:'余华'})
// .then(data => {
// console.log('文档读取成功', data);
// })
// .catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
//读取所有
BookModel.find()
.then(data => {
console.log('文档读取成功', data);
})
.catch(err => {
if (err) {
console.log('文档读取失败', err);
return;
}
})
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})
条件设置
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
// console.log("连接成功");
//5.创建文档的结构对象
let BookScheam = new mongoose.Schema({
//设置集合中文档的属性以及属性值的类型
name: String,
author: String,
price: Number,
is_hot: Boolean
})
//6.创建模型对象, 对文档操作的封装对象
let BookModel = mongoose.model('books', BookScheam)
/**
* > 使用 $gt
< 使用 $lt
>= 使用 $gte
<= 使用 $lte
!== 使用 $ne
*/
//读取所有价格小于20元的图书
// BookModel.find({price:{$lt:20}})
// .then(data => {
// console.log('文档读取成功', data);
// })
// .catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
// $or 逻辑或的情况
// $and 逻辑与的情况
// //读取曹雪芹或者余华的书
// BookModel.find({ $or: [{author:'曹雪芹'},{author:'余华'}] })
// .then(data => {
// console.log('文档读取成功', data);
// })
// .catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
// 价格大于30且小于70
// BookModel.find({ $and: [{ price: { $gt: 30 } }, { price: { $lt: 70 } }] })
// .then(data => {
// console.log('文档读取成功', data);
// })
// .catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
//正则表达式,搜索书籍名称中带有 三 的图书
// BookModel.find({name:/三/ })
// .then(data => {
// console.log('文档读取成功', data);
// })
// .catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
BookModel.find({name: new RegExp('三')})
.then(data => {
console.log('文档读取成功', data)
})
.catch(err => {
if (err) {
console.log('文档读取失败', err);
return;
}
})
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})
个性化读取
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
// console.log("连接成功");
//5.创建文档的结构对象
let BookScheam = new mongoose.Schema({
//设置集合中文档的属性以及属性值的类型
name: String,
author: String,
price: Number,
is_hot: Boolean
})
//6.创建模型对象, 对文档操作的封装对象
let BookModel = mongoose.model('books', BookScheam)
// 7.个性化读取
// 设置字段
//字段筛选
//0:不要的字段
//1:要的字段
// BookModel.find().select({ name: 1, author: 1, _id:0}).exec().then(data => {
// console.log('文档读取成功', data);
// }).catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
//数据排序
// 按照价格的升序排序
//sort 排序
//1:升序
//-1:倒序
// BookModel.find().select({ name: 1, _id:0 ,price:1}).sort({price:1}).exec().then(data => {
// console.log('文档读取成功', data);
// }).catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
//数据截取
//skip 跳过 limit 限定
//由高到低取出价格的前三名
// BookModel.find().select({ name: 1, _id:0 ,price:1}).sort({price:-1}).limit(3).exec().then(data => {
// console.log('文档读取成功', data);
// }).catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
//由高到低取出价格的4-6名
BookModel.find()
.select({ name: 1, _id: 0, price: 1 })
.sort({ price: -1 })
.limit(3)
.skip(3)
.exec()
.then(data => {
console.log('文档读取成功', data);
})
.catch(err => {
if (err) {
console.log('文档读取失败', err);
return;
}
})
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})
console.log(“连接关闭”);
})
## 个性化读取
```js
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4. 设置回调
//设置连接成功回调
mongoose.connection.once('open', () => {
// console.log("连接成功");
//5.创建文档的结构对象
let BookScheam = new mongoose.Schema({
//设置集合中文档的属性以及属性值的类型
name: String,
author: String,
price: Number,
is_hot: Boolean
})
//6.创建模型对象, 对文档操作的封装对象
let BookModel = mongoose.model('books', BookScheam)
// 7.个性化读取
// 设置字段
//字段筛选
//0:不要的字段
//1:要的字段
// BookModel.find().select({ name: 1, author: 1, _id:0}).exec().then(data => {
// console.log('文档读取成功', data);
// }).catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
//数据排序
// 按照价格的升序排序
//sort 排序
//1:升序
//-1:倒序
// BookModel.find().select({ name: 1, _id:0 ,price:1}).sort({price:1}).exec().then(data => {
// console.log('文档读取成功', data);
// }).catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
//数据截取
//skip 跳过 limit 限定
//由高到低取出价格的前三名
// BookModel.find().select({ name: 1, _id:0 ,price:1}).sort({price:-1}).limit(3).exec().then(data => {
// console.log('文档读取成功', data);
// }).catch(err => {
// if (err) {
// console.log('文档读取失败', err);
// return;
// }
// })
//由高到低取出价格的4-6名
BookModel.find()
.select({ name: 1, _id: 0, price: 1 })
.sort({ price: -1 })
.limit(3)
.skip(3)
.exec()
.then(data => {
console.log('文档读取成功', data);
})
.catch(err => {
if (err) {
console.log('文档读取失败', err);
return;
}
})
})
//设置连接错误回调
mongoose.connection.on('error', () => {
console.log("连接失败");
})
//设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log("连接关闭");
})