图书管理系统实现增删改查
在json文件中实现
(1) 使用json
使用三层架构 去写
第一层: index.js
第二层: router.js 路由封装
第三层: service.js 业务逻辑
创建主入口文件index.js
//引入相应模块
const express = require('express');
const bodyParser = require('body-parser');
const router = require('./routers/router1');
const path = require('path');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static('views'));
// express 兼容 art-template 模板引擎
// 设置模板引擎的路径
app.set('views',path.join(__dirname, 'views'));
// 设置模板引擎
app.set('view engine','art');
// 安装express-art-template
app.engine('art', require('express-art-template'));
// 路由规划设计 get post
// 使用配置路由
app.use(router);
app.listen(3000, () => {
console.log('runnning.......');
})
主入口文件写好后,后续就不需要进行改动
路由分配层
const express = require('express')
// 设置对于路由的处理的方法 Router()内置的路由处理的中间件
const router = express.Router()
const service = require('../service/service')
//显示json中的信息
router.get('/',service.showbook)
//跳转到添加书籍的页面
router.get('/toAddBook',service.toaddbook)
//提交书籍
router.post('/addbook',service.addbook)
//跳转到修改文件的页面
router.get('/toEditBook',service.toeditbook)
//提交修改的数据
router.post('/editbook',service.editbook)
//删除数据
router.get('/deleteBook/:id',service.deletebook)
//module.exports 提供了暴露接口的方法
module.exports = router
路由分配层编写时要注意路由名称要与art文件中对应
业务逻辑层
const data = require('../data.json')
const fs = require('fs')
const path = require('path')
//把主文件渲染到页面
exports.showbook=(req,res)=>{
res.render('index',{list:data})
}
//将添加书籍的文件渲染到页面
exports.toaddbook=(req,res)=>{
res.render('addbook')
}
//提交添加的数据,并写入json文件
exports.addbook=(req,res)=>{
//获取提交的信息
let info = req.body;
let arr = [];
data.forEach((i)=>{
arr.push(i.id)
})
let max = Math.max.apply(null,arr)
info.id=max+1;
console.log(info);
//将info中的数据写入data常量中
data.push(info)
//将data中的数据写入json文件
fs.writeFile(path.join(__dirname,'../data.json'),JSON.stringify(data),(err)=>{
if(err){
res.send('服务错误')
}
//写入成功的话就返回主页面
res.redirect('/')
})
}
//将修改渲染到页面,并将想要修改的数据显示到相应位置
exports.toeditbook=(req,res)=>{
//获取对应id
let id = req.query.id;
let result = {}
//将对应id中的数据提取出来
data.forEach((i)=>{
if(i.id==id){
result=i
}
})
//将获取的数据渲染到页面
res.render('editbook',result)
}
//将修改的数据写入文件
exports.editbook=(req,res)=>{
let info = req.body;
//将修改的数据付给对应id的对象中的值
data.forEach((i)=>{
if(info.id==i.id){
for(let key in info){
i[key]=info[key]
}
return
}
})
//将修改的值写入json文件
fs.writeFile(path.join(__dirname,'../data.json'),JSON.stringify(data),(err)=>{
if(err){
res.send('服务失败')
}
//修改成功后返回主页面
res.redirect('/')
})
}
exports.deletebook=(req,res)=>{
let id = req.params.id;
data.forEach((i,index)=>{
if(id==i.id){
data.splice(index,1)
}
})
fs.writeFile(path.join(__dirname,'../data.json'),JSON.stringify(data),(err)=>{
if(err){
res.send('服务失败')
}
//修改成功后返回主页面
res.redirect('/')
})
}
业务逻辑层的暴露出去的方法名称要与路由分配层所引用的一致
相关文件
主页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图书管理系统</title>
<style>
.title{
text-align: center;
color: black;
background-color: rgb(20, 87, 187);
height: 50px;
line-height: 50px;
}
.content{
background-color: gold;
}
.content table{
width: 100%;
text-align: center;
border-left: 1px solid orange;
border-top: 1px solid orange;
}
.content td{
border-left: 1px solid orange;
border-top: 1px solid orange;
}
a{
list-style: none;
text-decoration: none;
color: red;
}
</style>
</head>
<body>
<div class="title">图书管理系统<a href="/toAddBook">添加图书</a></div>
<div class="content">
<table>
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>作者</th>
<th>分类</th>
<th>描述</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{{each list}}
<tr>
<td>{{$value.id}}</td>
<td>{{$value.name}}</td>
<td>{{$value.author}}</td>
<td>{{$value.category}}</td>
<td>{{$value.desc}}</td>
<td><a href="/toEditBook?id={{$value.id}}">编辑</a>|<a href="/deleteBook/{{$value.id}}">删除</a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</body>
</html>
添加文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>添加图书</title>
</head>
<body>
<form action="/addbook" method="post">
书名: <input type="text" name="name" id=""><br>
作者: <input type="text" name="author" id=""><br>
类别: <input type="text" name="category" id=""><br>
描述: <input type="text" name="desc" id=""><br>
<input type="submit" value="确定">
</form>
</body>
</html>
修改文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>添加图书</title>
</head>
<body>
<form action="/editbook" method="post">
<input type="hidden" name="id" value="{{id}}">
书名: <input type="text" name="name" id="" value="{{name}}"><br>
作者: <input type="text" name="author" id="" value="{{author}}"><br>
类别: <input type="text" name="category" id="" value="{{category}}"><br>
描述: <input type="text" name="desc" id="" value="{{desc}}"><br>
<input type="submit" value="确定">
</form>
</body>
</html>
优化:在上面的代码中有很多重复的方法,可以将它封装成一个函数,直接调用来节省代码量
连接数据库实现
在MySQL数据库中,name和desc是内置的关键字,无法使用.所以使用bname,bauthor,bcatadory,bdesc
为了与数据库一一对应,需要修改art文件
<form action="/addbook" method="post">
书名: <input type="text" name="bname" id=""><br>
作者: <input type="text" name="bauthor" id=""><br>
类别: <input type="text" name="bcategory" id=""><br>
描述: <input type="text" name="bdesc" id=""><br>
<input type="submit" value="确定">
</form>
<form action="/editbook" method="post">
<input type="hidden" name="id" value="{{id}}">
书名: <input type="text" name="bname" id="" value="{{bname}}"><br>
作者: <input type="text" name="bauthor" id="" value="{{bauthor}}"><br>
类别: <input type="text" name="bcategory" id="" value="{{bcategory}}"><br>
描述: <input type="text" name="bdesc" id="" value="{{bdesc}}"><br>
<input type="submit" value="确定">
</form>
<tbody>
{{each list}}
<tr>
<td>{{$value.id}}</td>
<td>{{$value.bname}}</td>
<td>{{$value.bauthor}}</td>
<td>{{$value.bcategory}}</td>
<td>{{$value.bdesc}}</td>
<td><a href="/toEditBook?id={{$value.id}}">编辑</a>|<a href="/deleteBook/{{$value.id}}">删除</a></td>
</tr>
{{/each}}
</tbody>
修改完成后,只需要修改业务逻辑层的代码即可
修改业务逻辑层
为了优化代码,这里我引入了一个已经打包好的数据库的调用方法,
只需要添加sql语句以及data数据就可以实现数据库操作
//引入mysql
const mysql = require('mysql')
//暴露base方法
exports.base=(sql,data,callback)=>{
var connection = mysql.createConnection({
host:'localhost',
user:'root',
password:'root',
database:'mybook'
})
connection.connect()
connection.query(sql,data,(err,result)=>{
if(err)throw err;
callback(result)
})
connection.end()
}
const data = require('../data.json')
const fs = require('fs')
const path = require('path')
const db = require('../db')
//把主文件渲染到页面
//把主文件渲染到页面
exports.showbook=(req,res)=>{
//执行查询语句并不需要传入数据,因此将data定义为空
let sql = 'select * from book';
let data = {}
//执行查询操作返回的值是查询出的数据,是一个对象,所以这里直接将返回值渲染到页面上
db.base(sql,data,(result)=>{
res.render('index',{list:result})
})
}
//将添加书籍的文件渲染到页面
exports.toaddbook=(req,res)=>{
res.render('addbook')
}
exports.addbook=(req,res)=>{
//接受提交的值
let info = req.body;
console.log(info);
let sql = 'insert into book set ?'
db.base(sql,info,(result)=>{
//判断受影响的数据,如果为一条则代表修改成功
if(result.affectedRows==1){
res.redirect('/')
}
})
}
//根据id将值渲染到页面上
exports.toeditbook=(req,res)=>{
let id = req.query.id;
let sql = 'select * from book where id=?'
let data=[id]
db.base(sql,data,(result)=>{
//因为返回值是一个数组,因此需要加上索引值
res.render('editbook',result[0])
})
}
exports.editbook=(req,res)=>{
let info = req.body;
let sql = 'update book set bname=?,bauthor=?,bcategory=?,bdesc=? where id=?'
let data = [info.bname,info.bauthor,info.bcategory,info.bdesc,info.id]
db.base(sql,data,(result)=>{
if(result.affectedRows==1){
res.redirect('/')
}
})
}
exports.deletebook=(req,res)=>{
let id = req.params.id;
let sql = 'delete from book where id=?'
db.base(sql,id,(result)=>{
if(result.affectedRows==1){
res.redirect('/')
}
})
}
版权声明:本文为weixin_47723644原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。