node.js搭建简易CRUD图书系统

本文详细介绍了如何使用Express框架和Art-template模板引擎搭建一个图书管理系统,包括项目初始化、模板引擎配置、数据处理、服务层创建及数据持久化到MySQL数据库的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据持久化采用文件保存或mysql数据库两种方式

一、项目初始化

1、创建mybook文件夹

2、创建入口文件index.js

3、初始化项目生成package.json

npm init -y

4、安装依赖

npm install express art-template express-art-template body-parser --save

5、编辑入口文件 index.js

1)定义依赖
/**
图书管理系统入口文件
*/
const express = require('express');
const router = require('./router.js');
2)创建app对象
const app = express();
3)启动服务器,配置路由
// 启动服务器功能
// 配置路由
app.use(router);
4)监听端口
// 监听端口
app.listen(3000,()=>{
    console.log('running...');
});

6、创建路由文件router.js

/*
    路由模块
*/
const express = require('express');
const router = express.Router();

// 路由处理
// 渲染主页
router.get('/',(req,res)=>{
    console.log('主页');
    res.send('主页');
});

// 添加图书(跳转到添加图书的页面)
router.get('/addBook',(req,res)=>{
    console.log('添加图书');
    res.send('添加图书');
});

// 编辑图书(跳转到编辑图书信息页面)
router.get('/editBook',(req,res)=>{
    console.log('编辑图书');
    res.send('编辑图书');
});

module.exports = router;

7、测试

1)启动服务
node .
2)访问定义的路由

http://localhost:3000

http://localhost:3000/addBook

http://localhost:3000/editBook

二、添加模板引擎

1、引入模板引擎

1)定义依赖

在index.js中添加依赖

const template = require('art-template');
const path = require('path');
2)设置模板引擎

在index.js中添加

// 设置模板的路径
app.set('views',path.join(__dirname,'views'));
// 设置模板引擎
app.set('view engine','art');
// 使express兼容art-template模板引擎
app.engine('art', require('express-art-template'));

2、创建模板文件

1)创建views文件夹
2)创建文件views/index.art
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图书管理系统</title>
</head>
<body>
    
    <div>图书管理系统<a href="/addBook">添加图书</a></div>
    <div>
        <table cellpadding="0" cellspacing="0">
            <thead>
                <tr>
                    <th>编号</th>
                    <th>名称</th>
                    <th>作者</th>
                    <th>分类</th>
                    <th>描述</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>1</td>
                    <td>西游记</td>
                    <td>吴承恩</td>
                    <td>文学</td>
                    <td>佛教与道教的斗争</td>
                    <td><a href="#">修改</a>|<a href="#">删除</a></td>
                </tr>
                <tr>
                    <td>1</td>
                    <td>西游记</td>
                    <td>吴承恩</td>
                    <td>文学</td>
                    <td>佛教与道教的斗争</td>
                    <td><a href="#">修改</a>|<a href="#">删除</a></td>
                </tr>
                <tr>
                    <td>1</td>
                    <td>西游记</td>
                    <td>吴承恩</td>
                    <td>文学</td>
                    <td>佛教与道教的斗争</td>
                    <td><a href="#">修改</a>|<a href="#">删除</a></td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>
3)创建文件views/addBook.art
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图书管理系统-添加图书</title>
</head>
<body>
    <div>添加图书</div>
    <form action="/saveBook" method="post">
        名称:<input type="text" name="name"><br>
        作者:<input type="text" name="author"><br>
        分类:<input type="text" name="category"><br>
        描述:<input type="text" name="description"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>
4)创建文件views/editBook.art
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图书管理系统-修改图书</title>
</head>
<body>
    <div>修改图书</div>
    <form action="/updateBook" method="post">
        <input type="hidden" name="id" >
        名称:<input type="text" name="name" ><br>
        作者:<input type="text" name="author" ><br>
        分类:<input type="text" name="category" ><br>
        描述:<input type="text" name="description" ><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

3、调用模板

修改router.js

// 路由处理
// 渲染主页
router.get('/',(req,res)=>{
    ...
    res.render('index');
});

// 添加图书(跳转到添加图书的页面)
router.get('/addBook',(req,res)=>{
    ...
    res.render('addBook');
});

// 编辑图书(跳转到编辑图书信息页面)
router.get('/editBook',(req,res)=>{
    ...
    res.render('editBook');
});

三、处理数据

1、数据列表

1)创建json数据文件data.json
[
    {
        "id": "1",
        "name": "三国演义",
        "author": "罗贯中",
        "category": "文学",
        "desc": "一个杀伐纷争的年代"
    },
    {
        "id": "2",
        "name": "水浒传",
        "author": "施耐庵",
        "category": "文学",
        "desc": "108条好汉的故事"
    },
    {
        "id": "3",
        "name": "西游记",
        "author": "吴承恩",
        "category": "文学",
        "desc": "佛教与道教的斗争"
    },
    {
        "id": "4",
        "name": "红楼梦",
        "author": "曹雪芹",
        "category": "文学",
        "desc": "一个封建王朝的缩影"
    },
    {
        "name": "天龙八部",
        "author": "金庸",
        "category": "文学",
        "desc": "武侠小说",
        "id": 5
    }
]
2)router中引用json
const data = require('./data.json');

// 路由处理
// 渲染主页
router.get('/',(req,res)=>{
    ...
    res.render('index', {list : data});
});
3)模板中显示数据

修改index.art

<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="#">修改</a>|
            <a href="#">删除</a>
        </td>
    </tr>
    {{/each}}
</tbody>
4)重启服务测试

http://localhost:3000/

2、删除数据

1)修改index.art
<a href="/deleteBook?id={{$value.id}}">删除</a>
2)router中添加删除路由
// 删除图书
router.get('/deleteBook',(req,res)=>{
    console.log('删除图书');
    
    let id = req.query.id;
    data.forEach((item,index)=>{
        if(id == item.id){
            // 删除数组的一项数据
            data.splice(index,1);
        }
    });
    res.redirect('/');//页面跳转
});
3)测试

3、保存数据

1)index.js中定义依赖
const bodyParser = require('body-parser');
2)引入参数处理中间件

在index.js中启动服务的代码之前添加,这里要加在开头位置。

//挂载参数处理中间件(处理post表单)
// create application/x-www-form-urlencoded parser
app.use(bodyParser.urlencoded({extended: false}));
3)router中添加保存路由和辅助方法
// 自动生成图书编号(自增)
let maxBookCode = ()=>{
    let arr = [];
    data.forEach((item)=>{
        arr.push(item.id);
    });
    return Math.max.apply(null,arr);
};
// 保存图书(提交表单)
router.post('/saveBook',(req,res)=>{
    console.log('添加图书(提交表单)');
    
    let info = req.body;
    console.log(info);
    let book = {};
    for(let key in info){
        book[key] = info[key];
    }
    book.id = maxBookCode() + 1;
    data.push(book);

    res.redirect('/');//页面跳转
});
4)测试

4、根据id查询数据

1)修改index.art
<a href="/editBook?id={{$value.id}}">修改</a>
2)router中修改编辑图书的路由
// 编辑图书(跳转到编辑图书信息页面)
router.get('/editBook',(req,res)=>{
    console.log('编辑图书');
    // res.send('编辑图书');
    let id = req.query.id;
    let book = {};
    data.forEach((item)=>{
        if(id == item.id){
            book = item;
        }
    });
    res.render('editBook',book);
});
3)修改editBook.art页面
<form action="/updateBook" method="post">
    <input type="hidden" name="id" value="{{id}}">
     名称:<input type="text" name="name" value="{{name}}"><br>
     作者:<input type="text" name="author" value="{{author}}"><br>
     分类:<input type="text" name="category" value="{{category}}"><br>
     描述:<input type="text" name="description" value="{{description}}"><br>
     <input type="submit" value="提交">
</form>
4)测试

5、更新数据

1)router中添加更新路由
// 编辑图书(提交表单)
router.post('/updateBook',(req,res)=>{
    console.log('编辑图书提交表单');

    let info = req.body;
    data.forEach((item)=>{
        if(info.id == item.id){
            for(let key in info){
                item[key] = info[key];
            }
        }
    });
    
    res.redirect('/');//页面跳转
});
2)测试

四、创建服务层

1、数据列表

1)创建service.js文件

将对json数据的引入和辅助方法的定义从router.js中移植到service.js中

/*
    业务模块
*/
const data = require('./data.json');


// 自动生成图书编号(自增)
let maxBookCode = ()=>{
    let arr = [];
    data.forEach((item)=>{
        arr.push(item.id);
    });
    return Math.max.apply(null,arr);
};
2)在service中定义页面显示业务
// 渲染主页面
exports.showIndex = (req,res)=>{
    console.log('主页');
    res.render('index', {list : data});
};

// 添加图书
exports.addBook = (req,res)=>{
    console.log('添加图书');
    res.render('addBook');
};
3)router中引入service模块
const service = require('./service.js');
4)调用service模块中的方法

为了避免错误,先屏蔽其他的相关路由(除"/addBook"之外)

// 路由处理
// 渲染主页
router.get('/', service.showIndex);

// 添加图书(跳转到添加图书的页面)
router.get('/addBook', service.addBook);

2、编辑图书

1)在service中定义根据id查询指定图书的方法
// 编辑图书
exports.editBook = (req,res)=>{
    console.log('编辑图书');
    // res.send('编辑图书');
    let id = req.query.id;
    let book = {};
    data.forEach((item)=>{
        if(id == item.id){
            book = item;
        }
    });
    res.render('editBook',book);
};
2)修改router中的编辑图书的路由
// 编辑图书(跳转到编辑图书信息页面)
router.get('/editBook', service.editBook);

3、删除图书

1)在service中定义根据id删除指定图书的方法
// 删除图书
exports.deleteBook = (req,res)=>{
    console.log('删除图书');
    
    let id = req.query.id;
    data.forEach((item,index)=>{
        if(id == item.id){
            // 删除数组的一项数据
            data.splice(index,1);
        }
    });
    res.redirect('/');//页面跳转
};
2)修改router中的删除图书的路由
// 删除图书
router.get('/deleteBook', service.deleteBook);

4、保存图书

1)在service中定义保存图书的方法
// 保存图书
exports.saveBook = (req,res)=>{
    console.log('添加图书(提交表单)');
    
    let info = req.body;
    console.log(info);
    let book = {};
    for(let key in info){
        book[key] = info[key];
    }
    book.id = maxBookCode() + 1;
    data.push(book);

    res.redirect('/');//页面跳转
};
2)修改router中的保存图书的路由
// 保存图书(提交表单)
router.post('/saveBook', service.saveBook);

5、更新图书

1)在service中定义根据id更新指定图书的方法
// 编辑图书
exports.updateBook = (req,res)=>{
    console.log('编辑图书提交表单');

    let info = req.body;
    data.forEach((item)=>{
        if(info.id == item.id){
            for(let key in info){
                item[key] = info[key];
            }
        }
    });
    
    res.redirect('/');//页面跳转
};
2)修改router中的更新图书的路由
// 编辑图书(提交表单)
router.post('/updateBook', service.updateBook);

五、将数据持久化到json文件中

1、修改service

1)添加文件相关依赖

在service.js中添加

const path = require('path');
const fs = require('fs');
2)将数据写入json

在service.js中添加writeDataToFile方法,

// 把内存数据写入文件
let writeDataToFile = (res) => {
    // (data,null,4):保证数据存入的时候有换行缩进的格式
    fs.writeFile(path.join(__dirname,'data.json'),JSON.stringify(data,null,4),(err)=>{
        if(err){
            return false; // 文件写入失败
        }
        return true; // 文件写入成功
    });
};
3)调用写入文件的方法

在删除、保存、更新的业务方法中分别调用

writeDataToFile();

六、将数据持久化到MySQL数据中

1、初始化MySQL数据库和表

1)创建MySQL数据库 nodejs_book
CREATE DATABASE nodejs_book CHARACTER SET utf8 COLLATE utf8_general_ci;
2)创建数据库表 book
CREATE TABLE `book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255),
  `author` varchar(255),
  `category` varchar(255),
  `description` varchar(255),
  PRIMARY KEY (`id`)
);
3)执行MySQL脚本插入数据
insert into book (name,author,category,description) values ('三国演义','罗贯中','文学','一个杀伐纷争的年代');
insert into book (name,author,category,description) values ('水浒传','施耐庵','文学','108条好汉的故事');
insert into book (name,author,category,description) values ('西游记','吴承恩','文学','佛教与道教的斗争');
insert into book (name,author,category,description) values ('红楼梦','曹雪芹','文学','一个封建王朝的缩影');
insert into book (name,author,category,description) values ('天龙八部','金庸','文学','武侠小说');

2、引入mysql模块

1)安装模块
npm install mysql --save
2)创建db.config.js文件
//配置链接数据库参数
module.exports = {
    host : 'localhost',
    port : 3306,
    database : 'nodejs_book',
    user : 'root',
    password : '123456'
};
3)定义通用的db.js
/*
    定义数据库query函数
*/
var mysql = require('mysql');
var databaseConfig = require('./db.config.js');  //引入数据库配置模块中的数据

//向外暴露方法
module.exports = {
    base : (sql,params,callback) => {
         // 创建数据库连接
        const connection = mysql.createConnection(databaseConfig);  

        // 执行连接操作
        connection.connect(); 

        // 操作数据库(数据库操作也是异步的)
        connection.query(sql,params, function(error, results, fields) {
            if (error) throw error;
            callback(results);
        });

        // 关闭数据库
        connection.end();
    }
};

3、修改service

1)在service中引用db模块
const db = require('./db.js');
2)主页列表
// 渲染主页面
exports.showIndex = (req,res)=>{
    console.log('主页');
    let sql = 'select * from book';
    db.base(sql,null,(result)=>{
        res.render('index',{list : result});
    });
};
3)编辑图书(根据id选择)
// 编辑图书
exports.editBook = (req,res)=>{
    console.log('编辑图书');
    // res.send('编辑图书');
    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]);
    });
};
4)删除图书
// 删除图书
exports.deleteBook = (req,res)=>{
    console.log('删除图书');
    
    let id = req.query.id;
    let sql = 'delete from book where id=?';
    let data = [id];
    db.base(sql,data,(result)=>{
        if(result.affectedRows == 1){
            res.redirect('/');
        }
    });
};
5)保存图书
exports.saveBook = (req,res)=>{
    console.log('添加图书(提交表单)');
    
    let info = req.body;
    let book = {};
    for(let key in info){
        book[key] = info[key];
    }
    let sql = 'insert into book set ?';
    db.base(sql,book,(result)=>{
        if(result.affectedRows == 1){
            res.redirect('/');
        }
    });
};
6)更新图书
exports.updateBook = (req,res)=>{
    console.log('编辑图书提交表单');

    let info = req.body;
    let sql = 'update book set name=?,author=?,category=?,description=? where id=?';
    let data = [info.name,info.author,info.category,info.description,info.id];
    db.base(sql,data,(result)=>{
        if(result.affectedRows == 1){
            res.redirect('/');
        }
    });
};

七、展示

在这里插入图片描述在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值