NodeJs and Express学习笔记
目录
1、安装 nodemon
2、npm init
3、CommentJs、ES 模块化规则
3-1)CommentJS模块化
3-2)ES模块化
3-3)关于切换 commentJS 和 ES 规范:
4、内置模块 http
(1)使用 http 搭建自己的服务器
(2)使用 http 模块向其他服务器发送请求
5、WHATWG URL (用于解析路径)
6、QueryString 模块(查询字符串)
7、文件模块
(1) readFile 读取文件中的数据
(2)wtireFile 向指定文件中写入数据
(3)mkdir 创建一个目录
(4)rename 给目录(文件)重命名
(5)rmdir 删除一个空的目录
(6)appendFile 向文件中末尾添加内容
(7)unlink 删除指定文件
(8)readdir 查询指定目录下的文件
(9)stat 查询目录下的文件信息
(10)同步方法 existsSync() 判断路径是否存在(异步方法被弃用)
8、stream 流
(1)readStream
(2)writeStream
(3)pipe 管道
9、获取当前文件绝对路径的三种方法
10、express
10-1)简单使用
10-2)使用中间件
10-3)应用级中间件
10-4)路由级中间件
10-5)错误处理中间件
10-6)获取请求参数的方法
10-7)设置静态资源
10-8)Express生成器
11、使用 MongoDB 数据库
11-1)在nodejs中使用
11-2)常用命令
12、使用 MySql 数据库
1、安装 nodemon
npm i -g nodemon 全局安装nodemon
使用 nodemon 运行 nodejs 文件,当文件更改时,可以自动重新加载和运行。
2、npm init
npm init 可以创建一个package.json文件,该文件存放整个项目的配置数据,比如npm安装了哪些第三方包的工作都会有记录。
有了这个文件,当要把整个项目发给同事,就不用发node_model文件了(这个文件一般比较大,项目中所有的依赖文件都放在里面,比如第三方的工具库,就像要在项目中使用element-ui时,要用npm安装这个第三方库以应用到项目中)。对方可以在这个项目中打开终端,输入npm install (npm i) 安装package.json中记录的依赖包,package.json文件中有记录对应的版本信息。
3、CommentJs、ES 模块化规则
3-1)CommentJS模块化
/* a.js */
function getTime(){console.log((new Date()).getTime());
}
function print(){console.log("zhangsan");
}//第一种暴露方式,可以暴露多个在对象中
module.exports={getTime,print
}//第二中暴露方式,需要依次暴露 对应解构赋值的方式接收
exports.getTime=getTime;
exports.print=print;/* b.js */
const a = require('./a');
a.getTime()//解构赋值的方式接收
const {print} = require('./a');
print();
3-2)ES模块化
// 1、默认暴露
export default {name: 'John',age: 18
}// 引入:
import person from './person.js'
console.log(person.name) // John
// 2、命名暴露
export const name = 'John'
export const age = 18// 引入
import { name, age } from './person.js'
console.log(name) // John
// 3、统一暴露
const name = 'John'
const age = 18
export { name, age }// 引入:
import { name, age } from './person.js'
console.log(name) // John
// 4、混合暴露
const name = 'John'
const age = 18
export { name }
export default age// 引入:
import age, { name } from './person.js'
console.log(name) // John
console.log(age) // 18
// 5、统一暴露
const name = 'John'
const age = 18
export { name, age }// 引入 导入整个模块
import * as person from './person.js'
console.log(person.name) // John
console.log(person.age) // 18
3-3)关于切换 commentJS 和 ES 规范:
在package.json文件中更改type属性即可。

两种方式不能混用。
4、内置模块 http
(1)使用 http 搭建自己的服务器
第一种写法
// 引入 http 模块
const http = require("http");const server = http.createServer((request, response) => {//request 接收浏览器传的参数//response 返回渲染的内容// 设置响应体内容response.write("Hello world");response.write("[1,2,3,4,5,6]");//写入html标签// response.writeHead(200,{"Content-Type":"text/html;charset=utf-8"});// response.write(`// // Hello World// 早上好
// // `// );// write 向浏览器写入完信息之后要调用 response.end() 方法表示写入完成,// 不然浏览器就会一直加载(转圈圈),一直等end()response.end();// end()调用后,不能再 write
});server.listen(3000, () => {console.log("server start");
});
const http = require("http");const server = http.createServer((request, response) => {// request.url 在控制台打印访问服务器的路径console.log(request.url);//根据不同的路径执行不同的任务if(request.url === '/home'){response.writeHead(200,{"Content-Type":"text/html;charset=utf-8"});response.write(`Home`)}else{// plain是默认的文本形式,如果要显示中文的话,需要加上charset=utf-8// 如果要单纯返回json数据,可以写application/json;ico类型:image/x-iconresponse.writeHead(200,{"Content-Type":"plain;charset=utf-8"});response.write("404 not found");}response.end();
});server.listen(3000);
第二种写法
const http = require("http");const server = http.createServer();// 响应请求 监听 (收到一个请求时触发)
server.on("request", (request, response) => {response.writeHead(200, { "Content-Type": "plain;charset=utf-8" });response.end(JSON.stringify({data: [1, 2, 3, 4, 5, 6, 7],name: "zhangsan",age: 19,}));
});server.listen(3000);
(2)使用 http 模块向其他服务器发送请求
使用 get 方法发送get请求
// 因为大多数请求都是 GET 请求且不带请求主体,所以 Node.js 提供了该便捷方法。
// 该方法与 http.request() 唯一的区别是它设置请求方法为 GET 且自动调用 req.end()。
http.get('http://nodejs.org/dist/index.json',res=>{const {statusCode} = res;if(statusCode === 200){res.setEncoding('utf-8');// 保存响应数据let data = '';// 监听有数据返回事件,将数据一点一点地写入先前声明的 data 中res.on('data',chunk=>{data += chunk;})// 数据返回错误res.on('error',err=>{console.log(err);})// 所有返回的数据都处理好,便可以使用数据res.on('end',()=>{console.log(data);})}else{console.log('错误');// 消耗响应数据以释放内存res.resume();}})
使用 request 方法发送 其他 请求,以 post 为例
// 设置请求的参数
const postData = querystring.stringify({name:"zhangsan",age:'15'
});const options = {hostname: 'localhost',port: 3000,path: '/test',method: 'POST',headers: {'Content-Type': 'application/x-www-form-urlencoded','Content-Length': Buffer.byteLength(postData)}
};const req = http.request(options, (res) => {console.log(`状态码: ${res.statusCode}`);res.setEncoding('utf8');res.on('data', (chunk) => {console.log(`响应主体: ${chunk}`);});res.on('end', () => {console.log('响应中已无数据。');});
});req.on('error', (e) => {console.error(`请求遇到问题: ${e.message}`);
});// 写入数据到请求主体 携带的请求参数
req.write(postData);
// 使用 http.request() 必须总是调用 req.end() 来表明请求的结束,即使没有数据被写入请求主体。
req.end();
https 模块向其他服务器发送请求 与 http 类似,也有 get、request 方法。
5、WHATWG URL (用于解析路径)
(官网中的图片)

// 内置模块 直接引入
const {URL} = require('url');// 将要解析的路径
const urlstr = 'http://user:pass@sub.host.com:8080/p/a/t/h?query=string#hash';// console.log(URL);const myUrl = new URL(urlstr);console.log(myUrl);

6、QueryString 模块(查询字符串)
escape(编码)、unescape(解码)
parse(解析字符串为对象)、stringify(将对象转成字符串格式,中间用‘&’号间隔)
const querystring = require('querystring');// 目的字符串
const str='x=3&b=4&name=zhangsan';
// 将字符串解析为变成对象
const str1=querystring.parse(str);
console.log(str1);// 目标对象
const obj={a:2,name:"zhangsan",age:15,
}
// 将对象转成字符串格式
const obj1=querystring.stringify(obj);
console.log(obj1);
![]()
7、文件模块
以下全部都是异步方法,但他们也有配套的同步方法。即在原有的方法名后添加一个‘Sync’的后缀即为其同步方法。如 readFile 的同步方法为 readFileSync。
如果有必要进行同步执行,可以使用Promise方法来解决。
(1) readFile 读取文件中的数据
const fs = require('fs');// 调用函数readFile异步读取文件的全部内容
// 第一个参数是路径
// 第二个参数是编码的格式,默认会返回一个buffer类型的数组
// 第三个参数是一个回调函数。当读取成功时,err为null;当读取失败时,data为undefined,err为一个对象
fs.readFile('./wordFile/九月九日忆山东兄弟.txt','utf8',function(err,data){if(err) throw err;console.log(data);//如果不指定第三个参数 可以使用toString()方法//console.log(data.toString(‘utf-8’));
});
(2)wtireFile 向指定文件中写入数据
const fs = require('fs');const content = `静夜思唐 李白床前明月光,疑是地上霜。举头望明月,低头思故乡。`;// 调用writeFile异步地写入数据到文件(覆盖),如果文件已经存在,则替代文件,不存在则先创建文件
// 第一个参数是写入文件的地址
// 第二个参数是要写入的内容
// 第三个参数是可选的,指定编码格式,默认为utf8
// 第四个参数是一个回调函数,只有一个参数error,返回错误的信息,如果写入成功,则err为null
fs.writeFile('./wordFile/静夜思.txt',content,(err)=>{if(err){console.log(err);}else{console.log("写入成功!");}
})
(3)mkdir 创建一个目录
const fs = require('fs');//第一个参数指定目录名称
fs.mkdir('./newdir',(err)=>{if(!err){console.log("finish");}else{console.log(err);}
})
(4)rename 给目录(文件)重命名
const fs = require('fs');// 第一个参数为旧的目录地址,第二个参数为新的目录地址(改目录名)
fs.rename('./newdir','./olddir',(err)=>{if(!err){console.log("finish");}else{console.log(err);}
})// 改文件名
// fs.rename('./files/aaa.txt','./files/newa.txt',(err)=>{//...
// })
(5)rmdir 删除一个空的目录
// 如果目录中的内容不为空,则可以正常删除
// 如果目录中仍有文件,则不能正常删除,可以先用unlink依次把目录下的文件删除,然后再删除该目录
const fs = require('fs');
//第一个参数为该目录的地址
fs.rmdir('./olddir',(err)=>{//目录不存在则 err 中 的 code 为 ‘ENOENT’if(err){console.log(err);}
})
(6)appendFile 向文件中末尾添加内容
//向文件末尾追加内容,该方法不自动在开头换行
const fs = require('fs');fs.appendFile('./newdir/a.txt','\n你好',err=>{if(err){console.log(err);}
})
(7)unlink 删除指定文件
const fs = require('fs');fs.unlink('./newdir/a.txt',err=>{if(err){console.log(err);}
})
(8)readdir 查询指定目录下的文件
const fs = require('fs');fs.readdir('./newdir',(err,data)=>{if(err){console.log(err);
}else{//返回的是一个数组,每一项都是字符串类型的文件名console.log(data);}
})
(9)stat 查询目录下的文件信息
// 查询文件或目录的信息
const fs = require('fs');fs.stat('./newdir',(err,data)=>{if(err){console.log(err);}else{//返回目录或文件信息console.log(data);//判断是不是一个文件 返回boolean值console.log(data.isFile());//判断是不是一个目录 返回Boolean值console.log(data.isDirectory());}
})
(10)同步方法 existsSync() 判断路径是否存在(异步方法被弃用)
fs.existsSync(Path : String) : boolean
8、stream 流
以数据流的形式来读写文件
(1)readStream

第二个参数可以是一个字符串或一个对象,如果 option 是一个字符串,则它指定字符编码。
const fs = require('fs');const rs = fs.createReadStream('./1.txt','utf-8');
//有可能触发多次,即要读取的文件过大时,数据将一部分一部分的读出,每次触发一次
rs.on('data',chunk=>{console.log('chunk',chunk);
})
//全部数据读完之后触发 只触发一次
rs.on('end',(data)=>{console.log('end',data);
})
//读出数据过程中发生错误中触发
rs.on('err',(err)=>{console.log(err);
})

第二个配置对象中 highWaterMark 为读取的字节数
{highWaterMark: 64 * 1024}
(2)writeStream


const fs = require('fs');const ws = fs.createWriteStream('./2.txt','utf-8');
//可以分多次写入
ws.write('111111111111111');
ws.write('222222222222222');
ws.write('3333333');//写入流程结束时调用
ws.end();
(3)pipe 管道
//适合对大文件复制
const fs = require('fs');const readStream = fs.createReadStream('./1.txt');
const writeStream = fs.createWriteStream('./2.txt','utf-8');//读入流 通过管道 让读入的数据依次写入文件 能控制读写能密切衔接
readStream.pipe(writeStream);// 如果2.txt文件中原来有内容在,则先删除2.txt文件中的内容,然后再将1.txt文件中的内容全部复制到2.txt文件中
9、获取当前文件绝对路径的三种方法
process.cwd()、__dirname:精确到上级目录
__filename:精确到文件名
设当前 js 文件的路径为 D:\nodejsStudy\test\index.js
console.log(process.cwd());
/* D:\nodejsStudy\test */console.log(__dirname);
/* D:\nodejsStudy\test */console.log(__filename);
/* D:\nodejsStudy\test\index.js */
10、express
npm i express 安装express
10-1)简单使用
const express = require('express');
const fs = require('fs');const app = express();//第一个参数可以接受正则表达式 如 ‘/ab?cd’ 匹配 /abcd 或/cd (abc)?表示三个符号同时可选或同时不选
//还可以设置占位符,如’/ab/:name/:age’,可以匹配 /ab/**/** **代表一个参数,如果没有两个参数,则匹配不了
app.get('/server',(req, res)=>{// res.write('Hello world');// res.end();// res.writeHead(200, {"Content-Type":"application/json;charset=utf-8"});// res.write(JSON.stringify({name:'zhangsan',age:'45'}));// res.end();// 给前端返回json数据res.send(JSON.stringify({name:'zhangsan',age:'45'}));
});app.listen(3000, ()=>{console.log("listening");
})
10-2)使用中间件
这里的中间件(Middleware)是指在处理HTTP请求时,位于请求和响应之间的一层处理程序。中间件可以对请求进行处理、修改请求头、响应头、请求体等,也可以将请求转发给下一个中间件或路由处理程序。
中间件一般都通过 app.use(xxx) 来使用。
中间函数示例:
const express =require('express');const app = express();// 设置中间方法来进行业务逻辑操作,也可以在其他的服务器中得到复用
// 第三个参数是执行下一个中间函数的必要调用,如果不调用next()则下一个中间函数不会被调用
// 中间函数 先声明,后使用
const func1 = function (req, res, next){console.log("there is func1");next(); // 只有执行了 next() 程序才能继续往下执行
}const func2 = function (req, res, next){console.log('there is func2');next();
}//信息返回给前端一般写在最后一个回调中
app.get('/server', [func1, func2], (req, res)=>{res.send('ok');
}).listen(3000,()=>{console.log('listening');
})//也可以直接写,不写成数组的形式
// app.get('/server', func1, func2, (req, res)=>{
// res.send('ok');
// }).listen(3000,()=>{
// console.log('listening');
// })
在浏览器中访问localhost:3000/server 在服务器控制台将输入以下内容,浏览器返回一个“ok”

10-3)应用级中间件
Express 应用层中间件是指在路由处理之前,对客户端请求进行处理的中间件。
const express = require ('express');const app = express();//先注册再使用,使用next执行下一步,没有调用next()那么后面的动作将被挂起,不再执行
const func1 = function(req, res, next){console.log('ok');console.log(req.url);next();
}//应用类型中间件。一般之间放在app上。
//放在前面,则后边的服务器要访问都要先经过前面的中间件
//两种方式
app.use(func1); //响应以下任何路径
// app.use('/home',func1); //只响应'/home'路径类型app.get('/home', (req, res)=>{res.send("home");
}).listen(3000, ()=>{console.log('listening');
})
上面的 func1 函数就是一个应用级中间件,每当有请求访问定义在 func1 后的服务,在服务端控制台都会输出一个“ok”和请求的路径。

常用的应用级(内置)中间件有:
1. express.json():解析请求体中的 JSON 数据。它会将请求体中的 JSON 数据解析成 JavaScript 对象,并将其作为 `req.body` 对象的属性,然后将控制权传递给下一个中间件函数。
如:app.use(express.json())
2. express.urlencoded():解析请求体中的 URL-encoded 数据,并将解析后的数据存储在 `req.body` 对象中。如:app.use(express.urlencoded({ extended: true }))
`extended` 参数是一个布尔值,用于指定是否使用 `qs` 库来解析 URL 编码数据。如果设置为 `true`,则使用 `qs` 库,否则使用 Node.js 内置的 `querystring` 模块。`qs` 库支持更多的解析选项,例如解析嵌套对象和数组,因此在处理复杂的 URL 编码数据时,建议将 `extended` 设置为 `true`。
3. express.static():提供静态文件服务,将指定目录下的静态文件(如 HTML、CSS、JavaScript、图像等)提供给客户端。如:app.use(express.static('public'))
public 目录中的文件就可以通过相对路径访问,例如 `http://localhost:3000/index.html`
4. express.cookieParser():解析 Cookie。
5. express.session():提供会话支持。
6. express.logger():记录请求日志。
7. express.compress():压缩响应数据。
8. express.methodOverride():支持 HTTP 方法的重载。
9. express.csrf():提供 CSRF 防护。
10. express.timeout():设置请求超时时间。如:app.use(express.timeout(10000))
11. express.responseTime():记录响应时间。
12. express.errorHandler():处理错误信息
10-4)路由级中间件
app.get('/path', (req, res, next) => {...}) 就是一个路由级中间件,它精准匹配到路径 /path 就会命中而进入执行其中的内容,如果需要往排在后面的其他中间件跳转,则可以使用 next() 继续往下执行,而如果不需要继续往下走,就在当前这个路由中间件就能完成任务把内容返回,那就不需要继续 next(),则第三个参数 next 就不用写:app.get('/path', (req, res) => {...}) 。
/* index2.js */const express = require('express');
const {router} = require('./router2.js');const app = express();//应用级别中间件
app.use(function(req, res, next){console.log('验证成功');next();
})// 也是应用级别中间件
// 匹配到'/aaa'后,跳转到 router 中继续往后执行
// 即 router 中的中间件是专门处理路径带有 /aaa/ 前缀的请求的
app.use('/aaa', router);app.listen(3000, ()=>{console.log("3000端口正在监听");
})
/* router2.js */
const express = require('express');
const router = express.Router();// 路由级别中间件 分别在 /aaa 下再匹配 /home、/login
// localhost:3000/aaa/home 命中
router.get('/home', (req, res)=>{res.send('home');
})// localhost:3000/aaa/login 命中
router.get('/login', (req, res)=>{res.send('login');
})exports.router = router;
10-5)错误处理中间件
错误处理中间件是一种特殊类型的中间件,用于捕获应用程序中的错误并进行处理。错误处理中间件通常在所有其他中间件之后定义,以确保它们能够捕获所有未处理的错误。
兜底中间件也可以被视为一种错误处理中间件,它通常用于处理在应用程序中未被其他中间件处理的错误或异常情况。
const express = require('express');
const {router} = require('./router2.js');const app = express();//应用级别中间件
app.use(function(req, res, next){console.log('验证成功');next();
})app.use('/aaa', router);// 错误中间件 (兜底中间件)
// 当前面的路径都匹配不到时,才命中该中间件。也可以next到后面的错误捕获中间件
app.use((req, res)=>{res.status(404).send('404 no found');
})// 错误处理中间件,需要放到最后,用来捕获错误
// 接收四个参数,第一个是错误内容err,最后一个next可以省略
app.use((err, req, res, next) => {console.error(err.stack);res.status(500).send('Something broke!');
});app.listen(3000, ()=>{console.log("3000端口正在监听");
})
10-6)获取请求参数的方法
获取 get 请求参数
router.get('/about', (req, res)=>{//获取get请求的参数console.log(req.query);console.log(req.params);res.send("OK");
})
获取 post 请求参数的方法
//能接受post的参数类型为 username=zhangsan&age=19 的形式
//前端需要设置请求头内容格式为 Content-Type: application/x-www-form-urlencoded
app.use(express.urlencoded({extended:false}));//能接受post参数为{name:'zhangsan',age:19}的形式
//前端需要设置请求头内容格式为 Content-Type: application/json
app.use(express.json());router.post('/about', (req, res)=>{//获取post参数 还需要配置中间件console.log(req.body);res.send({status:200});
})
10-7)设置静态资源
当注册多个静态资源文件夹时,Express会按照注册的顺序依次查找文件,如果在第一个文件夹中找到了请求的文件,则直接返回该文件,否则继续在下一个文件夹中查找,直到找到该文件或者所有文件夹都被查找完毕。如果所有文件夹都被查找完毕仍然没有找到请求的文件,则会返回404错误。
const express = require('express');const app = express();// 注册两个文件夹
app.use(express.static('public'));
app.use(express.static('static'));app.post('/checked', (req, res)=>{res.writeHead(200,{'Access-Control-Allow-Origin':'*'});let data = '';req.on('data', chunk =>{data += chunk;});req.on('end', ()=>{data = JSON.parse(data);if(data['username'] === '张三' && data['password'] === '123456'){res.end('http://localhost:3000/home.html'); //验证成功,则跳转页面home(home.html)}else{res.end('http://localhost:3000/404.html'); //验证失败跳转到404页面(404.html)}})
});app.listen(3000, ()=>{console.log('listening');
})
另一种设置静态资源文件夹的方式:
app.use(‘/指定的路径名’, express.static(‘指定的静态文件夹名’));
app.use('/static',express.static('static'));
则后端返回资源时,需要加上指定的路径,如:
// res.end('http://localhost:3000/home.html');// 要改写成:res.end('http://localhost:3000/static/home.html');
10-8)Express生成器
安装:
npm install -g express-generator 全局安装
npx express-generator 局部安装
创建完毕之后,根据package.json文件,在生成器文件夹下打开终端运行npm i ,安装好依赖 node_module。

项目的入口文件:./bin/www
启动项目方式:node ./bin/www 或npm start。
可以更改 node 为 nodemon,这样可以使用 nodemon ./bin/www 运行。
(nodemon是一个Node.js应用程序的自动重启工具,它可以监视Node.js应用程序中的文件变化,并在文件发生变化时自动重启应用程序,从而加快开发效率。)
安装nodemon :npm i nodemon

10-8)获取和修改cookie
使用 cookie-parser:npm i cookie-parser
//引入 cookieParser
var cookieParser = require('cookie-parser');//使用 cookierParser 中间键
app.use(cookieParser());//获取cookies
let cookies = req.cookies;
console.log(cookies);//修改cookies
res.cookies('键','值');
res.send()
前端设置cookie:
document.cookie = 'loaction=dalian';document.cookie = "username=John Doe; expires=" + new Date(new Date().getTime() + 24 * 60 * 60 * 1000).toUTCString();
键: loaction,值: dalian
11、使用 MongoDB 数据库
11-1)在nodejs中使用
安装模块:npm i mongoose
如果当前版本没有自带data文件夹,需要先启动 mongod.exe,并配置好 dbpath。
创建一个config文件夹,在其中创建一个db_config.js文件,专门配置mongodb数据库模块。

/* config / db_config.js */// 先引入
const mongoose = require('mongoose');// 链接数据库 固定前缀 mongodb 127.0.0.1:27017 是本机域名,端口号默认为27017
// 也可以连接到别的主机,操作别人的数据库
// user-project为数据库名字,可以是已有的,也可以是要新建的,如果没有则会自动创建
mongoose.connect('mongodb://127.0.0.1:27017/user-projct');
在 bin/www 中直接 require(‘../config/db_config.js’);即可。
再创建一个model文件夹,在该文件夹下创建一个模型文件(如userModel),该模型跟数据库中的集合相对应,该模型文件可以限制集合的字段和每个字段的数据类型。(模型可以复用!)

创建 user.js :
/* model / user.js */const mongoose = require('mongoose');// Mongoose 的一切始于 Schema。
// 每个 schema 都会映射到一个 MongoDB collection ,并定义这个collection里的文档的构成。
const Schema = mongoose.Schema;// 设置有多少个字段 字段名,每个字段对应的数据类型
const UserTypr = {userName:String,password:String,age:Number
}// 创建一个名为 User的模型,那么在数据库中会创建一个集合Users (即加了一个后缀-s)
// 所以一般给模型起名字的时候,最好不要在加上-s的后缀
// 第二个参数为一个 Schema 对象 ,表示该模型中的字段分别需要运用什么类型的数据限制
const UserModel = mongoose.model('User',new Schema(UserTypr));module.exports = UserModel;
在需要使用的routers文件中引入 该模型文件,然后就能对该模型进行操作了。
const UserModel = require('../model/user');
一些基本的操作方法:
// 给模型(集合)添加一条数据
UserModel.create({userName,password,age // 对象的简写形式
})
// 注意,UserModel.xxx()返回一个Promise对象 ,可以使用.then() 方法处理其他事物// 修改更新替换 updateOne是只更新第一项(如果找到了多个匹配项)
// updateMany 是更新所有的匹配项
// 第一个参数用于提供指定内容,按照提供的内容来对数据进行检索
// 第二个参数是需要更新的字段名,以及相应的新的参数值,可以是多个
UserModel.updateOne({_id:'1235'},{username:'xxx',password:'xxx',age:1
});// 删除数据的方法
// deleteOne 和 deleteMany
UserModel.deleteOne({_id:'12346'
});// 查找全部数据 如果返回的数据只有一条或者是空,那么会是对象的形式{};如果返回来的有多条数据,会以数组的形式[{},{}]
UserModel.find().then(data=>{res.send(data);
})// 查找全部数据 指定返回的字段 即只显示age和userName
UserModel.find({},['age','userName']).then(data=>{res.send(data);
})// 返回时根据指定内容排序 -1是降序 1 是升序
UserModel.find().sort({'age':-1}).then(data=>{res.send(data);
})
11-2)常用命令
基本:
| 序号 | 目的 | 使用 | 备注 |
| 1 | 查看命令提示 | help db.help() db.test.help() db.test.find().help() | |
| 2 | 创建、切换数据库 | use xxx xxx为集合名称 | |
| 3 | 创建集合 | 1、db.createCollection(“xxx”) xxx为集合名称
表示最大储存空间设置为5m,最多放5000个文档的集合。当集合超过规定数量,将把最早的集合挤出空间,以保持最大5000个文档的数量 | |
| 4 | 查询数据库 | show dbs | |
| 5 | 查看当前使用的数据库 | db/db.getName() | |
| 6 | 显示当前的DB状态 | db.stats() | |
| 7 | 查看当前DB版本 | db.version | |
| 8 | 查看当前DB的链接机器地址 | db.getMongo() | |
| 9 | 删除数据库 | db.dropDatabase() | |
| 10 | 查询指定名称的集合 | db.getCollection() | |
| 11 | 查询当前db的所有集合 | db.getCollectionNames() | |
| 12 | 查询当前db所有集合的状态 | db.printCollectionStats() | |
| 13 | 删除指定集合 | db.xxx.drop() xxx表示某集合名称 |
增:
| 序号 | 目的 | 使用 | 备注 |
| 1 | 添加 | db.xxx.save({name:’zhangsan’,age:25}); 添加一项 db.xxx.save([{name:’zhangsan’,age:25},{name:’tiechui’,age:30},...]); 添加多项 |
改:
| 序号 | 目的 | 使用 | 备注 |
| 1 | 修改 | db.xxx.update({age:25},{$set:{name:’xiaonming’}}); 将age=25的项的name设置为xiaoming db.xxx.update({name:’list’,{$inc:{age:50}}); 将name=list的项的age增加50 db.xxx.update({name:’list’,{$inc:{age:-50}}); 将name=list的项的age减少50 |
删:
| 序号 | 目的 | 使用 | 备注 |
| 1 | 删除 | db.xxx.remove({age:132}); 删除age=132的所有项 db.xxx.remove({}); 删除集合中全部内容 |
查:
| 序号 | 目的 | 使用 | 备注 |
| 1 | 查询集合中所有记录 | db.xxx.find() | |
| 2 | 查询name字段去重后的数据 | db.xxx.distinct(‘name’) | 返回一个数组,由小到大 |
| 3 | 查询所有age为22的记录 | db.xxx.find({age:22}) | |
| 4 | 查询所有age大于22的记录 | db.xxx.find({age:{$gt:22}}) | |
| 5 | 查询所有age小于22的记录 | db.xxx.find({age:{$lt:22}}) | |
| 6 | 查询所有age大于等于22的记录 | db.xxx.find({age:{$gte:22}}) | |
| 7 | 查询所有age小于等于22的记录 | db.xxx.find({age:{$lte:22}}) | |
| 8 | 查询所有age大于等于23,小于等于50的记录 | db.xxx.find({age:{$gte:23,$lte:50}}) | |
| 9 | 查询所有name包含mongo的记录 | db.xxx.find({name:/mongo/}) | |
| 10 | 查询所有name以mongo开头的记录 | db.xxx.find({name:/^mongo/}) | |
| 11 | 查询所有数据,只显示age、name和_id列 | db.xxx.find({},{age:1,name:1}) | 第二个对象中,需要显示的列设置为1,不需要显示的列设置为0。如果有三个键,将_id设置为0,则只返回age和name两个键值 |
| 12 | 查询age大于25的全部数据,只显示name、_id列 | db.xxx.find({age:{$gt:25}},{name:1,age:0}) | |
| 13 | 查询全部数据并以升序返回 | db.xxx.find().sort({age:1}) | |
| 14 | 查询全部数据并以降序的形式返回 | db.xxx.find().sort({age:-1}) | |
| 15 | 查询name为zhangsan,age为25的所有记录 | db.xxx.find({age:25,name:’zhangsan’}) | |
| 16 | 查询五条记录 | db.xxx.find().limit(5) | |
| 17 | 查询第十条以后的所有记录 | db.xxx.find().skip(10) | 相当于跳过n条记录 |
| 18 | 查询第五条5至第10条之间的记录 | db.xxx.find().skip(5).limit(5) | |
| 19 | 查询age为25或50的全部记录 | db.xxx.find({$or:[{age:25},{age:50}]}) | |
| 20 | 查询第一条数据 | db.xxx.findOne() | |
| 21 | 查询集合中age大于25的项的记录条数 | db.xxx.find({age:{$gte:25}}).count() |
注意:使用use first 创建first数据库,当first中没有任何内容(集合)时,使用show dbs不会显示有first这个数据库;在使用db.createCollection(‘xxx’)后,first数据库中有一个xxx集合,此时调用show dbs会显示有first这个数据库,即便这个集合xxx是空的。
在终端中使用:在 D:\MongoDB\Server\4.4\bin 目录下启动终端,输入: .\mongo.exe ;回车运行。
12、使用 MySql 数据库
使用 mysql2 :npm i mysql2
连接前的配置:
const express = require('express');
const mysql = require('mysql2');const config = { // 连接数据库的一个配置项host:'127.0.0.1', // 数据库服务器的地址user:'username', // 连接数据库的用户名port:3306, // 连接数据库的端口号password:'psword', // 连接数据库的密码database:'peoples', // 要连接的数据库名称connectionLimit:1 // 创建一个连接池
}
const app = express();// 注意 async - await
app.get('/666',async (req, res)=>{// 根据配置,生成一个数据库连接池const promisePool = mysql.createPool(config).promise();// 普通的写法,直接写 SQL 语句,没有其他参数let resulta = await promisePool.query('select * from student');let name = '张三';// 要使用到参数,则可以使用问号占位,第二个数组参数中的内容会对应替换掉问号let resultb = await promisePool.query('select * from student where name = ? and id = ?',[name,15]);// 也可以用模板字符串的写法 有双引号的地方要保留双引号let resultc = await promisePool.query(`select * from student where name = "${name}"`);console.log(resulta[0]);res.send('ok');
});app.listen(3000,()=>{console.log('3000 is listening');
})
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
