node服务器与数据库对接小案例
数据交互图
## 英雄案例的后台接口实现
之前以前用ajax实现了英雄数据管理已经完成前台页面的业务处理
之前是提供了服务器,我们只需要进行接口的调用
现在,我们的任务是自己来实现这些个后台接口
目标
回顾数据库,数据表的创建和数据的模拟输入
回顾Express创建服务器
回顾Express的静态页面和静态资源的托管
回顾Express中创建路由模块
回顾Express中的第三方中间件的使用
理解和掌握文件上传的后台处理–新内容
1.body-parser
2.mysql
3…
进一步理前后台的交互流程
进一步理解前台,node服务器,mysql服务器的关系
创建数据库,表及其数据的模拟输入
id 是唯一标识列
isdel是bit类型只有0和1,0代表删除
将图片拷贝到资源目录images下(t图片名称要写对)
添加模拟数据
搭建项目结构
1.拷贝之前的ajax案例的代码
2.nmp init -y(包初始化)
3.下包(案例所需的全部包)
- npm i express
- npm i body-parser
- npm i formidable
- npm i mysql
4.创建app.js>router.js>handler.js…
5.将所有的静态资源存放到公共目录>public
创建服务器
创建服务器
实现页面和静态资源托管
为了配合写好的前台页面的代码,我们参照前台页面的请求来设置端口号
--------------------app.js-----------------------
const express=require("express")
const path=express("path")
const app=express()
app.listen(3002,()={
console.log('http://127.0.0.1:3002')
})
//实现静态首页的托管
app.use("/",express.static(path.join(__dirname,"views")
//实现静态资源的托管
app.use(exress.static("public"))
分析后台所需要实现的接口
1.响应所有的英雄数据:get /getalldata
2.实现头像上传: post /uploadFile
3.新增英雄数据:post /add
4.根据id查询英雄数据 : get / getHeroByld
5.编辑英雄数据:post / edit
6 删除英雄数据 : get /detele
封装路由模块并使用
--------------------router.js-----------------------
//这个文件主要有路由模块封装(中间件)
//路由的主要功能是进行请求的处理分发,就是确定用户的请求到底应该由那个模块进行处理,所以一般就是调用模块的方法进行业务的处理
const express=require("express")
//引进路由模块
const router=express.Router()
//添加路由配置
//响应所有英雄数据:get /getalldata
router.get("/getalldata",(req,res)=>{
handler.getalldata(req.res)
})
// - 实现头像的上传: post /uploadFile
// - 新增英雄数据: post /add
// - 根据id查询英雄数据:get /getHeroById
// - 编辑英雄数据: post /edit
// - 删除英雄数据: get /delete
//暴露router
moduler.exports=router
--------------------app.js-----------------------
//在app.js 中引进 router的js
const router=require("./router")
// 在项目中明确的安装路由功能,让App应用使用router模块进行路由的处理
app.use(router)
业务1:响应所有英雄数据(第三方模块)
- 在路由模块中添加路由配置–router.js
- 在业务处理模块中实现所有英雄数据的查询–handler.js
//这个模块主要是进行用户请求的具体的业务处理
//引入mysql
const mysql=require("mysql")
//创建一个连接对象(数据库)
const connection=mysql.createPool({
//主机
host:"localhost",
//用户名
user:"root",
//密码
password:"root",
//数据库名
database:"mybase58"
})
实现所有英雄数据的查询并响应
--------------------handler.js-----------------------
module.exports={
//获取所有英雄数据
getalldata:function(req,res){
//1建立sql语句,查询要带一个条件,只要查询出没有删除的数据
let sql="select * from heros where isdel=0"
//2执行sql语句
//查询出来的结果是一个结果集,他是一个数组
connection.query(sql,(err,results)=>{
if(err){
console.log(err)
res.josn({code:204,
msg:"查询失败"
})
}else{
res.josn({code:204,
msg:"查询成功",
//记得要把查询的数据返回
data:results
})
}
})
}
}
路由模块中调用业务处理方法
--------------------router.js-----------------------
//响应英雄数据:get /getalldata
router.get("/getalldata",(req,res)=>{
handler.getalldata(req。res)
}
)
细节说明
1createPool不要显示的打开链接
2查询返回的是结果集,在代码中对应着数组
3后台返回数据的格式直接影响前台所接受数据的格式,如后台返回的属性是data,那和前台页面接收到的也是data
业务2:实现头像的上传
使用第三方模块:formidable
使用步骤
1.下载安装
2.引入
3.创建formidable对象
4.添加配置--如果不添加,有默认值
5.实现文件上传,同时,以回调函数的方式接受上传结果
常用配置
- encoding:参数的编码,如果是普通的键值对可以设置,上传文件不用设置
- uploadDir:上传文件的存储路径
- keepExtensions:是否保留扩展名,不保留不影响效果
实现文件上传
//实现文件上传
uplaodFile:function(req,res){
//1创建文件上传对象
let form=new IncomingForm()
//2添加必要的配置
//2.1设置上传恩建的存放路径,一定个给一个全路径,否则 报错
form.uploadDir=__dirname+"/public/images"
// 2.2 设置是否保留文件的扩展名,默认不保留
from.keepExtensions=true
// 3.调用上传方法,实现文件上传
// form.parse(请求报文,回调函数)
// err:文件上传失败时的错误信息
// fields:接收到普通键值对--对象
// files:文件的相关信息,特别是上传成功后在服务器端的信息
form.parse(req,(err,fields,files)=>{
if(err){
console.log(err)
res.json({code:204,
msg:"文件上传"
})
}esle{
res.json({
code:200,
msg:"文件上传成功",
//拿到图片的相对路径
img:path.basename(flies.img.path)
})
}
})
}
业务3-实现数据新增
-
- 添加路由配置–router.js
- 实现新增业务处理–handler.js
- 接收用户参数
- 创建sql语句,实现新增功能
路由配置
// - 新增英雄数据: post /add
router.post('/add', (req, res) => {
handler.add(req, res)
})
添加body-parser的使用
//这个模块的作用就是接收post方式所传递的普通键值对(不能用于上传文件)
let bodyParser=require("body-parser")
//添加body-parse解析器,以后有参数,就可以挂载到req.body属性上
app.use(bodyParser.json())//可以接收post方式所传递的json格式字符串
app.use(bodyParse.urlencode({extended:false})//接收带编码格式的字符串
实现新增业务处理
//新增英雄数据 :post /add
add:function(req,res){
//接收参数
let obj=req.body
// 实现新增,简洁语法要求:传入的数据参数对象的属性名称必须和表的字段名称完全一致,因为它会根据属性名称和值自动的生成Sql语句
let sql="insert into heros set ?"
connection.query(sql, obj,(err,results)=>{
if(err){
console.log(err)
res.json({code:204,
msg:"新增失败"
})
}else{
res.json({code:204,
msg:"新增成功"
})
}
})
}
业务4-根据id查询英雄数据
- 添加路由配置
- 查询英雄数据
- 接收参数id
- 根据id查询英雄数据
- 添加路由配置
// - 根据id查询英雄数据:get /getHeroById
router.get('/getHeroById', (req, res) => {
handler.getHeroById(req, res)
})
查询英雄数据
//根据id查询英雄数据:get /getHeroById
getHeroById: function (req, res) {
// 接收参数id
// req.query:在Express中,get方式所传递的参数存储在req.query中,它是一个对象 { id: '4' }
let id=req.query.id
//创建sql语句
let sql="select*from heros where id="+id
connection.query(sql,(err,results)=>{
if(err){
console.log(err)
res.json({
code: 204,
msg: '编辑失败'
})
}else{
res.json({
code: 204,
msg: '编辑失败',
// 一定要记得将查询到的数据返回
// 根据id查询出的数据最多只有一条,但是查询始终是返回结果集数组,所以我们可以直接获取数组中的第0个元素
data:results[0]
})
}
})
}
细节
- 在express中,get方式的参数通过req.query来获取,post方式的参数通过req.body来获取
- 查询返回结果集数组,如果有必要,可以将返回值进行简化处理
业务5-实现英雄数据的编辑
-
添加路由配置
-
实现英雄数据的编辑
- 接收用户参数
- 实现数据编辑
路由配置
// - 编辑英雄数据: post /edit
router.post('/edit', (req, res) => {
handler.edit(req, res)
})
实现英雄数据的编辑
// - 编辑英雄数据: post /edit
edit:function(req,res){
let obj=req.body
let sql ="update heros set ? where id=?"
connection.query(sql,[obj,obj.id],(err,results)=>{
if (err) {
console.log(err)
res.json({
code: 204,
msg: '编辑失败'
})
} else {
res.json({
code: 200,
msg: '编辑成功'
})
}
})
}
业务6-实现用户数据的删除
- 添加路由配置
- 实现数据的删除
- 接收参数
- 删除,我们采用是软删除
路由配置
// - 删除英雄数据: get /delete
router.get('/delete', (req, res) => {
handler.delete(req, res)
})
实现删除操作
// - 删除英雄数据: get /delete
delete:function(req,res){
let id=req.query.id
let sql ="update heros set isdel=1 wehere id="+id
connection.query(sql,(err,results)=>{
if (err) {
console.log(err)
res.json({
code: 204,
msg: '删除失败'
})
} else {
res.json({
code: 200,
msg: '删除成功'
})
}
})
}
细节
- 删除有两种常见的删除方式
- 硬删除:真正的将数据删除–delete
- 软删除:不是真正的删除,只是设置了删除标记,这个标记一般是数据表中的某个字段
常见错误
1没有将路由模暴露出来
2,路由块请求方式写错了