基于Express 下的 增删改查项目

基于Express 下的 增删改查项目

整体步骤:

  • 处理模块
  • 配置开放静态资源
  • 配置模板引擎
  • 简单路由: /students 渲染静态页面
  • 路由设计
  • 提取路由模块
  • 由于接下来一系列的业务操作都需要处理文件数据,所以我们需要封装一个 students.js 模块
  • 写好 students.js 文件结构
    • find 查询所有学生列表的 API
    • findById 查询单个学生的ID
    • save 保存学生信息
    • updateById 更新学生信息
    • deleteById 删除学生信息
  • 实现具体功能
    • 通过路由收到请求
    • 接受请求中的数据(get, post)
      • req.query
      • rqe.body
    • 调用数据操作API 处理数据
    • 根据数据结果给客户端发送响应
  • 业务功能处理顺序
    • 列表
    • 添加
    • 编辑
    • 删除

路由设计

请求方法 请求路径 get参数 post参数 备注
GET / 渲染首页
GET /new 渲染添加页面
POST /new name、age、gender、hobbies 处理添加请求
GET /edit id 渲染编辑页面
POST /edit id、name、age、gender、hobbies 处理编辑请求
GET /delete id 处理编辑请求

1.app.js

用来加载模块和模板引擎

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//  引入express 模块
const express = require('express')
const app = express()
const bodyParser = require('body-parser')

// 引入 touter.js 模块(自定义模块)
const router = require('./router')

// 在express中使用 art-template 模块引擎
app.engine('html', require('express-art-template'))

// 开放静态资源
app.use('/node_modules/', express.static('./node_modules/'))
app.use('/public/', express.static('./public/'))

//一定要放在 app.use(router) 挂载路由之前
// create application/json parser
app.use(bodyParser.json())
// create application/x-www-form-urlencoded parser
app.use(bodyParser.urlencoded({
extended: false
}))

// 把 router模块中 的 路由容器挂载在app这个服务上
app.use(router)

app.listen(3000, () => {
console.log('running...');
})

2.router.js

用来挂载路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const express = require('express')
const fs = require('fs')
const Student = require('./students.js')
// 创建一个路由容器
const router = express.Router()


// 把路由都挂载到 router 路由容器中
router.get('/', (req, res) => {

})
router.get('/new', (req, res) => {

})
router.post('/new', (req, res) => {


})
router.get('/edit', (req, res) => {

})
router.post('/edit', (req, res) => {

})
router.get('/delete', (req, res) => {

})
module.exports = router

2.1 调用 获取学生信息的封装函数

1
2
3
4
5
6
7
8
9
10
11
router.get('/', (req, res) => {
Student.find((err,students)=>{
if(err){
return res.status(500).send('Servererr..')
}
res.render('index.html',{
comments: ['苹果', '橘子', '香蕉', '菠萝'],
students: students
})
})
})

2.2 调用 添加并保存学生信息的封装函数

1
2
3
4
5
6
7
8
9
router.post('/new', (req, res) => {

Student.save(req.body, (err) => {
if (err) {
return res.status(500).send('Server err..')
}
res.redirect('/')
})
})

2.3 1.修改前 前调取 修改该学生的ID

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
router.get('/edit', (req, res) => {
// 1. 在客户端的列表页中处理链接问题 (需要有 id 的参数)
// 2. 获取要编辑的 id
// console.log(req.query.id);
// 3. 渲染编辑页面
// 根据id 吧学生信息查出来
// 使用模板引擎来渲染页面
Student.findById(parseInt(req.query.id), (err, student) => {
// req.query.id 是字符串 而我们要的 id 是个 数字型 所以要转换
if (err) {
return res.status(500).send('Server err..')
}
// console.log(studnet); id 是多 传过来的数据 就是 该 id 的对象
// 把 所取到该 id 对象的 值 来渲染到页面上
res.render('edit.html', {
student: student
})
})
})

2.3 2.调用 修改学生信息的封装函数

1
2
3
4
5
6
7
8
9
10
11
12
router.post('/edit', (req, res) => {
// 1. 获取表单数据 req.body
// console.log(req.body);
// 2. 更新 Student.updataById()
// 3. 发送响应
Student.updateById(req.body, (err) => {
if (err) {
return res.status(500).send('Server err..')
}
res.redirect('/')
})
})

2.4 调用 删除学生信息的封装函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
router.get('/delete', (req, res) => {
// 1. 在客户端的列表页中处理链接问题 (需要有 id 的参数)
// 2. 获取要编辑的 id
console.log(req.query.id);
// 3. 渲染编辑页面
// 根据id 把学生信息查出来
// 使用模板引擎来渲染页面
Student.deleteById(parseInt(req.query.id), (err, student) => {
// req.query.id 是字符串 而我们要的 id 是个 数字型 所以要转换
if (err) {
return res.status(500).send('Server err..')
}
res.redirect('/')
})
})

3.students.js

设计操作文件数据的API模块

用来处理增删改查数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/  数据文件操作模块
// 职责: 操作文件中的数据: 只处理数据 不处理业务


// 1. 获取所有学生信息列表
exports.find = () => {

}
// 1.1 通过ID 来获取 该学生的信息
exports.findById = () => {

}
// 2. 添加保存学生信息
exports.save = () => {

}


// 3. 更新学生信息
exports.updateById = () => {

}


// 4. 删除学生信息
exports.delete = () => {

}

3.1 获取所有学生信息封装函数

1
2
3
4
5
6
7
8
9
10
11
exports.find = (callback) => {
fs.readFile(dbPath, 'utf8', (err, data) => {
if (err) {
return callback(err)
}
// err 成功时返回 null 错误返回 err
// data 成功时返回 data 错误返回 undefined
callback(null, JSON.parse(data).students)
})
}

3.2 添加并保存学生信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// student 表示 添加的值
exports.save = (student, callback) => {
// 1. 读文件
fs.readFile(dbPath, 'utf8', (err, data) => {
if (err) {
return callback(err)
}
// 2. 转成对象
let students = JSON.parse(data).students

// 2.1处理id 唯一 不重复
student.id = students[students.length - 1].id + 1

// 3.把用户传递的对象push到数组中
students.push(student)

// 4.把对象转成字符串
let fileData = JSON.stringify({
students: students
})

// 5.把字符串保存在 文件中
fs.writeFile(dbPath, fileData, (err) => {
if (err) {
return callback(err)
}
callback(null)
})
})
}

3.3 修改学生信息

3.3.1 获得修改该学生个人ID

1
2
3
4
5
6
7
8
9
10
11
12
13
// 1.1  通过ID 来获取 该学生的信息
exports.findById = (id, callback) => {
fs.readFile(dbPath, 'utf8', (err, data) => {
if (err) {
return callback(err)
}
let students = JSON.parse(data).students
let ret = students.find((item) => {
return item.id === parseInt(id)
})
callback(null, ret)
})
}

3.3.2 修改学生信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 3. 更新学生信息
exports.updateById = (student, callback) => {
// 1. 读文件
fs.readFile(dbPath, 'utf8', (err, data) => {
if (err) {
return callback(err)
}
// 2. 转成对象
let students = JSON.parse(data).students
// 注意要把 id 改成数字型 因为 更改信息的时候 id会变成字符串
let studentsId = parseInt(student.id)
// 3.需要修改谁, 就把谁的ID找出来 (找出修改的 对象 )
// 使用 ES6 中 find 方法来 遍历符合 item.id === studnent.id 条件的时候, find会终止遍历并返回
let stu = students.find((item) => {
return item.id === studentsId
})
// console.log(stu); // { id: 1, name: '朱元璋111', gender: 0, age: 22, hobbies: '写代码' }
// 4. 拿到 需要修改的 让它遍历拷贝对象 ( 修改这个被找出来的 对象)
for (let key in student) {
stu[key] = student[key]
}
// console.log(students); // 是jsonw文件中的 students 内的 所有对象
// 5.把对象转成字符串
let fileData = JSON.stringify({
students: students
})

// 6.把字符串保存在 文件中
fs.writeFile(dbPath, fileData, (err) => {
if (err) {
return callback(err)
}
callback(null)
})



})

}

3.4 删除学生信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 4. 删除学生信息
exports.deleteById = (id, callback) => {
// 1. 读文件
fs.readFile(dbPath, 'utf8', (err, data) => {
if (err) {
return callback(err)
}
// 2. 转成对象
let students = JSON.parse(data).students

let deleteID = students.findIndex((item) => {
return item.id === parseInt(id)
})
students.splice(deleteID, 1)

// 4.把对象转成字符串
let fileData = JSON.stringify({
students: students
})

// 5.把字符串保存在 文件中
fs.writeFile(dbPath, fileData, (err) => {
if (err) {
return callback(err)
}
callback(null)
})

})
}