Node04


前言

本章学习内容 : 学生接口练习;简单的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 name like '%王%'' (姓名中包含 王 这个字的记录)
select * from student where name like ‘%王%’ or nickname like ‘%李%’
4.分页查询(对查询出的结果进行分页操作.对前面查询出来的结果进行分页.)
select * from student limit 起始下标,拿多少个
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参数 就是返回所有信息.

npm官方示例

//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: '删除成功'
        });
    });
});

总结

splice(开始下标,删除个数),includes(‘需要检测的字符串’)检测字符串是否包含括号里的字符串,返回值Boolean 本章主要的学习内容是node.js中使用mysql数据库模块(之前我们操作数据是通过文件夹)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值