前言
本章学习内容 : 学生接口练习;简单的sql语句复习 ; 在node.js中的使用mysql数据库,实现对数据的处理并响应回客户端 。
1. 学生接口练习
1.简单版:API:/api/student/list
method: get
参数:无
返回值:({
code: 状态码,
count: 学生信息总数,
data: 数据
})
//1. 导入express模块
const express = require('express');
//2. 创建应用
const app = express();
//3. 注册路由
app.get('/api/student/list', (req, res) => {
// 将所有的学生读取出来响应给浏览器.
//1. 读取学生库的数据
const stus = require('./data/stu.json');
//2. 响应给客户端
res.send({
code: 200,
count: stus.length,
data: stus
});
});
//4. 开启监听
app.listen(80, () => console.log('服务启动成功'));
2.带参数查询:
需求:要求客户端传递q参数.
q参数是可选的.
如果不传 就返回所有
如果传递了, 就查询name nickname中包含q
app.get('/api/student/list', (req, res) => {
//1. 读取学生库的数据
const stus = require('./data/stu.json');
//2. 判断客户端是否有传递q参数.
const { q } = req.query; // q = '花'
//准备1个数组 用来保存需要返回的数据.
let returnStus = [];
if(q){
//表示q传递了数据
//查询stus数组中符合条件的数据. name包含q 或者 nickname包含q
for(let i = 0; i <stus.length; i++ ){
if(stus[i].name.includes(q) || stus[i].nickname.includes(q)){
returnStus.push(stus[i]);
}
}
}else{
//这个表示没有传递q参数.
returnStus = stus;
}
//2. 响应给客户端
res.send({
code: 200,
count: returnStus.length,
data: returnStus
});
});
3.分页查询
page参数. 可选 如果没有传递 那么默认值就给1
app.get('/api/student/list', (req, res) => {
//1. 读取学生库的数据
const stus = require('./data/stu.json');
//2. 判断客户端是否有传递q参数.
// 取出客户端传递到服务端的参数 q page
let {q, page} = req.query; // q = '花'
// page参数是可选的,如果客户端不传递page参数,那么page的值默认1
page = page || 1;
const pageSize = 5; //每1页有多少条数据, 页容量 服务端固定5
//准备1个数组 用来保存需要返回的数据.
let tempStus = [];
if (q) {
//表示q传递了数据
//查询stus数组中符合条件的数据. name包含q 或者 nickname包含q
for (let i = 0; i < stus.length; i++) {
if (stus[i].name.includes(q) || stus[i].nickname.includes(q)) {
tempStus.push(stus[i]);
}
}
} else {
//这个表示没有传递q参数.
tempStus = stus;
}
// 对tempStus数组进行分页 获取数据.
// slice 从数组中截取1部分数据.
// 参数1: 起始下标
// 参数2: 结束下标(不包含结束下标)
const startIndex = (page - 1) * pageSize;
const endIndex = startIndex + pageSize;
// 0 5
// 根据页码和容量返回指定页的数据.
// 最后1页 3条. 如果第2个参数下标超出了数组的界限,那么实际有多少个 就取多少个.
const returnStus = tempStus.slice(startIndex, endIndex)
//2. 响应给客户端
res.send({
code: 200,
count: returnStus.length,
data: returnStus
});
});
4.删除接口
/api/student/delete
参数:id
需求:接收客户端传递过来的id, 然后将学生库中这个id的学生对象删除.
const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
app.get('/api/student/delete', (req, res) => {
//1. 获取客户端从URL传递过来的id参数
const {id} = req.query;
if (!id) return res.status(400).send({code: 400, msg: '参数错误'});
//说明id有传递.
// 去学生库中查找是否有这个id的学员.
// 如果有 则删除
// 如果没有 报404
const stus = require('./data/stu.json');
let flag = false; //旗帜.
for(let i = 0; i < stus.length; i++){
if(stus[i].id == id){
//当前遍历出来的这个对象的id和客户端传递过来的id相同
//删除
//写代码删除..........
stus.splice(i, 1); //这个只是删除数组中的元素.
flag = true;
break;
}
}
//循环结束以后
if(flag){
//说明,传递的id在数组中是存在的.
// 重写.
fs.writeFile(path.join(__dirname, 'data/stu.json'), JSON.stringify(stus), 'utf-8', err=>{
if(err) return res.status(500).send({code:500, msg:'服务器内部错误'});
res.send({code: 200, msg: '删除成功'});
});
}else{
//说明不存在.
res.status(404).send({code:404, msg:'id不存在'});
}
})
上述判断id是否存在, 用for循环来判断 存在的话splice(下标,数量)删除,并更新flag为turn(flag可以理解为是否存在id);还可以用some遍历stus 是否存在id。
上面的获取数据都是用fs模块获取文件中的文件,如果数据比较多,读取频繁,安全性和效率都不理想,接下来学习node.js通过第三方mysql模块,使用数据库操作数据。
2. 复习简单的SQL语句
2.1 新增
insert into 表名(字段名…) value(值…)
insert into student(name,nickname,gender,age,score,className,avatar)
value(‘热心网友小李’,‘李仔’, ‘男’, 18, 100, ‘珍珠班’, ‘huazai.jpg’)
2.2 删除
delete from 表名 where 条件.
delete from student where age>20
2.3 修改
update 表名 set 字段1=新值,字段2=新值… where 条件
update student set name=‘jack’ where id=1
2.4 查询
1. 单条件查询
select * from 表名where 条件
字段 关系 值.
select * from student where id=1
select * from student where age>=18
2. 多条件查询
select * from student where gender=‘女’ and score>=90
关键字:and (并且&&) or (或 | |)
3. 模糊查询(作用: 判断字段中是否包含指定的字符.)
like ‘%字符串%’
select * from student where namelike '%王%''
(姓名中包含 王 这个字的记录)
select * from student where name like ‘%王%’ or nickname like ‘%李%’
4.分页查询(对查询出的结果进行分页操作.对前面查询出来的结果进行分页.)
select * from studentlimit 起始下标,拿多少个
select * from student limit 0, 5
select * from student where name like ‘%王%’ or nickname like ‘%王%’ limit 0, 5
truncate table 表名 1. 将表中的数据清空 2. 并将id重置.
3. Node.js使用msql
1.项目文件夹npm i mysql
2.导入mysql 并使用(可以npm官网看示例)
案例1:通过关键字查询学生信息接口
需求
要求客户端的URL中带有1个q参数.
q 可选 如果有传递q参数: 查询name nickname中包含q的记录返回
没有q参数 就是返回所有信息.
//1. 导入模块
const express = require('express');
const mysql = require('mysql');
const connection = mysql.createConnection({
host: '127.0.0.1', //配置要操作的数据库的地址
user: 'root', //连接MySQL数据库的用户名
password: 'root', //连接MySQL数据库的密码
database: 'dbstudy' //要操作的数据库的名字
});
//2. 创建应用
const app = express();
app.get('/api/student/list', (req, res) => {
//0. 将客户端通过URL传递到服务端的q参数取出来.
const { q } = req.query;
//如果q有值,就意味着sql语句的后面要加1个where条件.
//1. 从数据库中将学生表中的所有数据查询出来返回.
//1.2 执行sql语句
let sqlCommand = 'select * from student';
if(q) sqlCommand += ` where name like '%${q}%' or nickname like '%${q}%'`;
//这个方法会去数据库执行sql语句 并且执行成功之后
connection.query(sqlCommand, (error, results) => {
if(error) return res.status(500).send({code:500, msg:'服务器内部错误', error});
//说明查询成功
// results中就是查询到的数据.
// results数组, 元素是1个1个的对象. 每一个对象就是一条记录.
res.send({
code: 200,
count: results.length,
data: results
});
});
})
const app = express();
mysql使用步骤:1.导入模块
2.定义一个connection = mysql.createConnection({连接数据库的参数})
3.connection.query(‘sql语句’,回调函数(中间件))----回调函数中有三个参数error(出现错误时存储错误信息) ,results(返回结果,查询语句返回的数据),files。
官方文档中connection.query()前后还有一个connection.connect();和connection.end();但是不去写这两个步骤,再次发起数据库请求会报错。
查询接口: 分页
参数: page 可选 如果没有传 page 1
app.get('/api/student/list', (req, res) => {
//0. 将客户端通过URL传递到服务端的q page参数取出来.
let {q, page} = req.query;
// 判断1下,page是否有传递 如果page没有传值 那么默认值就设置为1
page = page || 1; //2
// 定义1个变量 表示页容量.
const pageSize = 5;
//如果q有值,就意味着sql语句的后面要加1个where条件.
//1. 从数据库中将学生表中的所有数据查询出来返回.
//1.2 执行sql语句
// q=花&page=1
// 当前接口
// q page参数
// 都是可选的.
// q 没有值,查询所有 有值就查询满足条件的.
/*
1. 如果q参数没有值: select * from student limit (page-1)*size, size
2. 如果q参数有值: select * from student where name like '%q%' or nickname like '%q%' limit (page-1)*size, size
*/
let sqlCommand = 'select * from student';
if (q) sqlCommand += ` where name like '%${q}%' or nickname like '%${q}%'`;
//最后,需要为这个sql语句,加上分页的语句.
sqlCommand += ` limit ${(page - 1) * pageSize}, ${pageSize}`;
//这个方法会去数据库执行sql语句 并且执行成功之后
connection.query(sqlCommand, (error, results) => {
if (error) return res.status(500).send({code: 500, msg: '服务器内部错误', error});
//说明查询成功
// results中就是查询到的数据.
// results数组, 元素是1个1个的对象. 每一个对象就是一条记录.
res.send({
code: 200,
count: results.length,
data: results
});
});
})
案例3:post请求新增学生信息
API: /api/student/add
method: post
参数: 学生对象的字段.
name nickname gender age score className…
name nickname gender 这3个必须要传,否则报错400
其它的参数可选, 如果没有传递其它的参数,就设置1个默认值.
做的事情: 新增学生数据
返回的数据: {
code:
msg:
}
app.post('/api/student/add', (req, res) => {
//1. 先从post请求中取出传递的数据
const stu = req.body;
// 对数据进行一些校验.
// name nickname gender这三个数据是必须要传递,否则就报400
if (!stu.name || !stu.nickname || !stu.gender) return res.status(400).send({code: 400, msg: '参数错误'});
//3个必传的数据都有了.
//判断1下其它的参数是否有传递,如果有传递,就是它传递的值, 如果没有传递我们就设置1个默认值.
stu.age = stu.age || 18;
stu.score = stu.score || 60;
stu.className = stu.className || '深圳黑马前端就业班第71期';
stu.avatar = stu.avatar || 'default_avatar.png';
//2. 生成sql语句,执行.
const sqlCommand = `insert into student(name,nickname,gender,age,score,className,avatar)
value('${stu.name}', '${stu.nickname}', '${stu.gender}', ${stu.age}, ${stu.score}, '${stu.className}','${stu.avatar}')
`;
//3.执行sql语句
connection.query(sqlCommand, (error, results) => {
if (error) return res.status(500).send({code: 500, msg: '服务器内部错误', error});
//sql语句执行成功
// 如果sql语句是一个insert新增语句
// 那么这个时候 results 就是1个 对象
// affectedRows: 执行sql语句,受影响的行数.
// insertId 新增的数据在数据库中的id
//console.log(results)
//res.send('ok');
res.status(201).send({
code: 201,
msg: '新增成功',
insertId: results.insertId
})
});
});
案例4:删除对应id的学生信息
API: /api/student/delete
Method: get
参数: id.
做的事情: 删除对应的学生 id不存在. 404
返回的数据: {
code:
msg:
}
app.get('/api/student/delete', (req, res) => {
//1. 取出客户端通过URL传递到服务端的id
const {id} = req.query;
//2. 判断id是否有传递
if (!id) return res.status(400).send({code: 400, msg: '参数错误'});
//3. 生成sql语句
const sqlCommand = 'delete from student where id=' + id;
//4. 执行sql语句
connection.query(sqlCommand, (error, results) => {
if (error) return res.status(500).send({code: 500, msg: '服务器内部错误', error});
//说明语句执行成功
//delete from student where id=50
// 删除语句执完毕之后, results 是1个对象,affectedRows 表示受影响的行数.
if (results.affectedRows == 0) { //受影响的行数为0
return res.status(404).send({code: 404, msg: 'id不存在'});
}
//有受影响的行数.
res.send({
code: 200,
msg: '删除成功'
});
});
});