node.jsday06
目录
前言
node.jsday06学习开始
一、复习
二、mysql模块
- 专门用于操作mysql数据库的模块,属于第三方模块,先下载安装
- npm install mysql
- createConnection()--创建连接对象,需要提供数据库的参数,以及要进入的数据库名称
- createPool()--创建连接池对象,可以一次创建多个连接
multipleStatements: true 开启允许同时执行多条SQL命令
- connect()--测试数据库连接
- query(SQL命令, (err, r)=>{ })--执行SQL命令,是异步操作,通过回调函数获取结果
err--SQL命令中可能产生的语法错误
r--SQL命令执行成功的结果
SQL注入:在让用户提供一个值的时候,结果用户提供的值破坏了原来的SQL命令结构,加入了新的条件或者命令。
select * from emp where "1";
mysql模块防止SQL注入:
占位符(?),数组中的值会自动过滤,过滤完会替换占位符
c.query('select * from emp where ename=?', [过滤的值], (err,r)=>{})
SQL命令的执行结果
查询数据 数组
插入数据 对象
删除数据 对象
修改数据 对象
// 引入mysql模块 const mysql = require('mysql') // 创建连接对象 const c = mysql.createConnection({ host: '127.0.0.1', port: '3306', user: 'root', password: '', database: 'tedu' }) // 测试连接 // c.connect() // 执行SQL命令,会自动连接 c.query('select * from dept',(err,r)=>{ // err SQL命令中可能出现的语法错误 if(err) { throw err } // r 成功的结果 console.log(r) }) // 练习:执行SQL命令,查询出姓名为xin的员工 c.query('select * from emp where ename="xin"',(err,r)=>{ if(err) { throw err } console.log(r) }) // 练习:假设已经从客户端获取了传递的员工姓名(可以先放入到变量),执行SQL命令,查询出员工姓名对应的这条数据 var str = 'xxx" or "1' //'select * from emp where ename="xxx" or "1"' c.query(`select * from emp where ename="${str}"`,(err,r)=>{ if(err) { throw err } console.log(r) }) var str = 'xin' var n = '8000' // 问号(?):占位符,等过滤完再自动替换 // 第二个参数是数组,存放就是要过滤的值,里边会自动被过滤 c.query(`select * from emp where ename=? or salary>?`,[str,n],(err,r)=>{ if(err) { throw err } console.log(r) }) // 练习:假设获取了客户端传递的一条员工数据,格式为对象,包含的属性有姓名,性别,生日,工资,部门编号;执行SQL命令,将这条数据插入到数据库中。 var obj = { ename: '新哥', sex: '0', birthday: '1983-8-1', salary: '50000', deptid: '20' } c.query('insert into emp values(null,?,?,?,?,?)',[obj.ename,obj.sex,obj.birthday,obj.salary,obj.deptid],(err,r)=>{ if(err) { throw err } console.log(r) }) var obj = { salary: '50000', ename: '新哥2', // sex: '0', // birthday: '1983-8-1', deptid: '20' } // 对象的属性名可以缺少,会自动使用默认值 // 属性的顺序可以错乱 c.query('insert into emp set ?',[obj],(err,r)=>{ if(err) { throw err } console.log(r) }) // 练习:假设获取了客户端传递的员工编号(保存到变量),执行SQL命令,删除编号对应的员工 var eid = '19' c.query('delete from emp where eid=?',[eid],(err,r)=>{ if(err) { throw err } console.log(r) // r 成功的结果是对象,如果对象下的affectedRows属性值为0说明删除失败,否则删除成功 if(r.affectedRows===0){ console.log('删除失败') }else{ console.log('删除成功') } }) // 练习:假设获取到了客户端传递的要修改的一条员工数据,格式为对象,包含的属性有编号、姓名、性别、生日、工资、部门编号,执行SQL命令,修改编号对应的这个员工 var obj = { eid: '20', ename: 'xin888', sex: '1', birthday: '1978-8-20', salary: '82888', deptid: '10' } c.query('update emp set ? where eid=?',[obj,obj.eid],(err,r)=>{ if(err) { throw err } console.log(r) // r 结果是对象,如果对象下的属性changedRows值为0说明修改失败,否则就是修改成功 if(r.changedRows===0){ console.log('修改失败') }else{ console.log('修改成功') } })
三、接口
- 接口(API):就是后端为前端提供动态资源
- 返回结果
是JSON格式,特点:是字符串形式的对象,属性名是双引号,属性值是字符串的话也是用双引号.
返回结果中包含状态码和消息说明,如果需要响应这一组数据,还需添加属性
'{"code": 200, "msg":"查询成功", "data": [ ... ] }'
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client 响应了多次,例如:多次send方法调用
四、mysql模块练习
练习1:编写脚本文件03_tedu.js,使用express创建WEB服务器,设置端口,托管静态资源到public目录,包含文件search.html,点击提交向服务器端发请求(get /search),获取传递的姓名,到数据库中查询该员工,最后响应‘查询成功’
练习2:在public下添加文件add.html,点击提交向服务器端发请求(post /add),获取传递的参数,执行SQL命令,将这条数据插入到数据库,最后响应{code:200,msg:'员工添加成功'}
文件目录结构
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>add.html添加员工</title> </head> <body> <form action="/add" method="post"> 姓名<input type="text" name="ename"><br> 性别<input type="text" name="sex"><br> 生日<input type="text" name="birthday"><br> 工资<input type="text" name="salary"><br> 部门编号<input type="text" name="deptid"><br> <button>提交</button> </form> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>search.html查找员工</title> </head> <body> <form action="/search" method="get"> 姓名 <input type="text" name="ename"> <button>查找</button> </form> </body> </html>
// 02_pool.js // 引入mysql模块 const mysql = require('mysql') // 创建连接池对象 const pool = mysql.createPool({ host: '127.0.0.1', port: '3306', user: 'root', password: '', database: 'tedu', connectionLimit: '15', // 开启允许同时执行多条SQL命令 multipleStatements: true }) // 执行SQL命令,会自动从连接池中获取一个连接,执行完就会把这个连接还回去 pool.query('select * from dept;select * from emp where eid=1',(err,r)=>{ if(err) { throw err } //r 同时执行多个SQL命令,返回的结果是一个数组 console.log(r[0]) console.log(r[1]) })
// 03_tedu.js // 引入express模块 const express = require('express') // 引入mysql模块 const mysql = require('mysql') // 创建WEB服务器 const app = express() // 设置端口 app.listen(3000,()=>{ console.log('服务器启动成功') }) // 托管静态资源 app.use( express.static('public') ) // 创建连接池对象 const pool = mysql.createPool({ host: '127.0.0.1', port: '3306', user: 'root', password: '', database: 'tedu', connectionLimit: '15' }) // 添加路由(get /search) // 1.查找员工接口 app.get('/search',(req,res)=>{ // 获取get传递的参数 var obj = req.query console.log(obj) // 执行SQL命令,查询该员工 pool.query('select * from emp where ename=?',[obj.ename],(err,r)=>{ if(err) { throw err } console.log(r) // 如果查询结果是空数组说明员工不存在,否则就是存在 // 空数组长度为0 if(r.length===0){ // send方法会自动将JS对象转为JSON res.send({code: 400,msg:'该员工不存在'}) }else{ res.send({code: 200,msg: '查找成功',data: r}) } }) }) // 将post传参转为对象 app.use( express.urlencoded({ extended: true }) ) // 2.添加员工接口(post /add) // 接口地址(请求的URL):http://127.0.0.1:3000/add // 请求方式(请求方法):post app.post('/add', (req,res)=>{ // 获取post传递的参数 var obj = req.body console.log(obj) // 执行SQL命令,将数据插入到数据库 pool.query('insert into emp set ?',[obj],(err,r)=>{ if(err) { throw err } console.log(r) // 直接响应成功 res.send({code:200,msg:'员工添加成功'}) }) })
总结
node.jsday06学习结束