在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 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_47723644/article/details/109391642