基于node.js的express框架的图书管理功能(2)

  之前的图书管理功能的数据是存放在json文件中的,通过读取json文件的内容渲染到页面上,每次读取都要遍历整个文件,当数据量大时很不方便,把数据存放在数据库中才是正确的做法。

1.操作数据库的基本功能

在Mysql中新建一个数据库book,新建一张book的表用来存放图书的数据信息,将id值设为自增。

利用数据库自增功能有一个问题:在执行删除操作后,再添加数据时,id会出现间隔现象,如下图:

数据库搭建好后,创建一个项目测试一下数据库操作的一些基本功能:

新建一个文件夹mydb

准备一个入口文件:index.js

初始化该项目:npm init -y

安装需要的依赖的包:

npm install mysqljs/mysql

①插入数据

/**
 * 插入数据
 */
//加载数据库驱动
const mysql = require(‘mysql‘);
//创建数据库链接
const connection = mysql.createConnection({
    host: ‘localhost‘,   //数据库所在的服务器的域名或者IP地址
    user: ‘root‘,      //登录数据库的账号
    password: ‘password‘,
    database: ‘book‘    //数据库的名称book,注意这里不是链接的名称,我创建的链接的名称为mybook
});
//执行连接操作
connection.connect();
//使用mysql第三方包简化了insert操作,?用来填充数据,只需要提供一个对象
let sql = ‘insert into book set ?‘
//用来插入的数据
let data = {
    name: ‘明朝那些事‘,
    author: ‘当年明月‘,
    category: ‘文学‘,
    description: ‘明朝的历史‘
}

//操作数据库
connection.query(sql,data,(err,results,fields) => {
    if(err) return;
    //console.log(results);
    if(results.affectedRows == 1){
        console.log(‘数据插入成功‘);
    }
});
//关闭数据库
connection.end();

②更新数据

/**
 * 更新数据
 */
//加载数据库驱动
const mysql = require(‘mysql‘);
//创建数据库链接
const connection = mysql.createConnection({
    host: ‘localhost‘,   //数据库所在的服务器的域名或者IP地址
    user: ‘root‘,      //登录数据库的账号
    password: ‘password‘,
    database: ‘book‘    //数据库的名称book,注意这里不是链接的名称,我创建的链接的名称为mybook
});
//执行连接操作
connection.connect();

let sql = ‘update book set name=?,author=?,category=?,description=? where id=?‘
//用来更新的数据
let data = [‘浪潮之巅‘,‘吴军‘,‘计算机‘,‘IT巨头的兴衰史‘,6];

//操作数据库
connection.query(sql,data,(err,results,fields) => {
    if(err) return;
    //console.log(results);
    if(results.affectedRows == 1){
        console.log(‘数据更新成功‘);
    }
});
//关闭数据库
connection.end();

③删除数据

/**
 * 删除数据
 */
//加载数据库驱动
const mysql = require(‘mysql‘);
//创建数据库链接
const connection = mysql.createConnection({
    host: ‘localhost‘,   //数据库所在的服务器的域名或者IP地址
    user: ‘root‘,      //登录数据库的账号
    password: ‘password‘,
    database: ‘book‘    //数据库的名称book,注意这里不是链接的名称,我创建的链接的名称为mybook
});
//执行连接操作
connection.connect();

let sql = ‘delete from book where id=?‘
//用来删除的数据
let data = [6];

//操作数据库
connection.query(sql,data,(err,results,fields) => {
    if(err) return;
    //console.log(results);
    if(results.affectedRows == 1){
        console.log(‘数据删除成功‘);
    }
});
//关闭数据库
connection.end();

④查询数据

/**
 * 操作数据库基本步骤
 */
//加载数据库驱动
const mysql = require(‘mysql‘);
//创建数据库链接
const connection = mysql.createConnection({
    host: ‘localhost‘,   //数据库所在的服务器的域名或者IP地址
    user: ‘root‘,      //登录数据库的账号
    password: ‘password‘,
    database: ‘book‘    //数据库的名称book,注意这里不是链接的名称,我创建的链接的名称为mybook
});
//执行连接操作
connection.connect();

let sql = ‘select * from book‘
let data = null;

//操作数据库
connection.query(‘select 1+1 as solution‘,(err,results,fields) => {
    if(err) return;
    console.log(results[0]);
});
//关闭数据库
connection.end();

上述的增删改查的代码有很多重复性,可以将以上功能封装为一个通用的api文件db.js:

/**
 * 封装操作数据库的通用API
 */
const mysql = require(‘mysql‘);

exports.base = (sql,data,callback) => {
    //创建数据库链接
    const connection = mysql.createConnection({
        host: ‘localhost‘,   //数据库所在的服务器的域名或者IP地址
        user: ‘root‘,      //登录数据库的账号
        password: ‘password‘,
        database: ‘book‘    //数据库的名称book,注意这里不是链接的名称,我创建的链接的名称为mybook
    });
    //执行连接操作
    connection.connect();

    //操作数据库(数据库操作也是异步的,异步不同通过返回值来处理,只能通过回调函数)
    connection.query(sql,data,(err,results,fields) => {
        if(err) throw err;
        callback(results);
    });
    //关闭数据库
    connection.end();
}

测试该api:

/**
 * 测试通用API
 */
const db = require(‘./db.js‘);

//插入操作
let sql = ‘insert into book set ?‘;
let data = {
    name: ‘笑傲江湖‘,
    author: ‘金庸‘,
    category: ‘文学‘,
    description: ‘武侠小说‘
};
db.base(sql,data,(result) => {
    console.log(result);
});

//更新操作
let sql = ‘update book set name=?,author=?,category=?,description=? where id=?‘;
let data = [‘天龙八部‘,‘金庸‘,‘文学‘,‘武侠小说‘,5];
db.base(sql,data,(result) => {
    console.log(result);
});

//删除操作
let sql = ‘delete from book where id=?‘
let data = [7];
db.base(sql,data,(result) => {
    console.log(result);
});

//查询操作
let sql = ‘select * from book where id = ?‘;
let data = [8];
db.base(sql,data,(result) => {
    console.log(result);
});

2.通过一个小的登陆验证功能来测试前后端+数据库一起的功能:

后台逻辑代码login.js:

/**
 * 登陆验证(前端+后端+数据库)
 */
const express = require(‘express‘);
const bodyParser = require(‘body-parser‘);
const db = require(‘./db.js‘);
const app = express();
//启动bodyParser这个API来处理参数,处理表单提交的
app.use(bodyParser.urlencoded({extended:false}));
app.use(express.static(‘./public‘));

app.post(‘/check‘,(req,res) => {
    let param = req.body;
    console.log(param);
    let sql = ‘select count(*) as total from user where username=? and password=?‘;
    let data = [param.username,param.password];

    db.base(sql,data,(result) => {
        console.log(result);
        if(result[0].total == 1){
            res.send(‘login success!‘);
        }else{
            res.send(‘login failure!‘);
        }
    });
});

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

前端页面代码login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>登录</title>
</head>
<body>
    <form action="http://localhost:3000/check" method="POST">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登录">
    </form>
</body>
</html>

3.重构图书管理功能,使数据从数据库中获取

将操作数据库的通用api文件db.js拷贝到mybook项目下,还需要安装mysql的api

注意:由于desc字段在数据库中是关键字,不能使用,所以把该字段名称改为description,之前的.art文件里用到的desc字段名称全部要改过来,否则执行过程中会报错

只需修改service.js业务模块中的功能:

/**
 * 业务模块
 */
const data = require(‘./data.json‘);
const path = require(‘path‘);
const fs = require(‘fs‘);
const db = require(‘./db.js‘);

/* //自动生成图书编号(自增)
let maxBookCode = () => {
    let arr = [];
    data.forEach(item => {
        arr.push(item.id);
    });
    return Math.max.apply(null,arr);
}

//把内存数据写入到文件
let writeDataFile = (res) => {
    //需要把内存中的数据写入文件
    //JSON.stringify(data)仅传data一个参数的话,data.json文件是压缩形式的
    fs.writeFile(path.join(__dirname,‘data.json‘),JSON.stringify(data,null,4),(err) => {
        if(err){
            res.send(‘server err‘);
        }
        //文件写入成功之后重新跳转到主页面
        res.redirect(‘/‘);
    });
}
 */
 //渲染主页面
 exports.showIndex = (req,res) => {
     let sql = ‘select * from book‘;
    //从数据库中获取内容
    db.base(sql,null,(result) => {
        //数据库获取的内容只能通过回调函数来得到
        res.render(‘index‘,{list:result});
    })
    //res.render(‘index‘,{list:data});
 }

 //跳转到添加图书的页面
 exports.toAddBook = (req,res) => {
     //render将会根据views中的模板文件进行渲染,渲染的是空对象{}
     res.render(‘addBook‘,{});
 }

 //添加图书保存数据
 exports.addBook = (req,res) => {
     //获取表单数据
     let info = req.body;
     let book = {};
     for (const key in info) {
         book[key] = info[key];
     }

     let sql = ‘insert into book set ?‘
     db.base(sql,book,(result) => {
         if(result.affectedRows == 1){
             //添加成功后跳转到主页面
             res.redirect(‘/‘);
         }
     });

     /* book.id = maxBookCode()+1;
     data.push(book);
     //需要把内存中的数据写入文件
     writeDataFile(res); */
 }

 //跳转到编辑页面
 exports.toEditBook = (req,res) => {
    let id = req.query.id;
    let sql = ‘select * from book where id=?‘;
    let data = [id];
    db.base(sql,data,(result)=>{
        //注意:必须使用result[0]获取数据才能渲染到页面上,因为得到的resul结果集是一个数组,不是对象,渲染不了
        res.render(‘editBook‘,result[0]);
    });
    /* let book = null;
    data.forEach((item)=>{
        if(id == item.id){
            book = item;
            //break;
            //forEach循环中不能有break,用return终结即可
            return;
        }
    });
    //render将会根据views中的模板文件进行渲染,渲染的是对应图书的完整信息
    res.render(‘editBook‘,book); */
 }

 //编辑图书更新数据:
 //1.先查询出对应的数据并渲染到页面上
 //2.然后再提交表单,再重新保存,写入文件
 //编辑的时候要告诉服务器编辑的是哪条数据
 exports.editBook = (req,res) => {
    //报错:为什么总是跳转到addBook的页面?  问题已解决:editBook.art页面的action路径错写成‘/addBook‘,改成‘/editBook‘就可以正常运行
    //获取表单的数据
    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(‘/‘);
        }
        else{
            res.send(‘edit failure‘);
        }
    });

     /* //覆盖原有的数据
     data.forEach((item)=>{
         if(info.id == item.id){
             for (const key in info) {
                 item[key] = info[key];
             }
             return;
         }
     });
     //需要把内存中的数据写入文件
     writeDataFile(res); */
 }

 //删除图书信息
 exports.deleteBook = (req,res) => {
     //先获取到传过来的id
     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(‘/‘);
        }
    });

    /*  data.forEach((item,index)=>{
         if(item.id == id){
            //删除数组的一项数据
            data.splice(index,1);
         }
         return;
     });
     //需要把内存中的数据写入文件
     writeDataFile(res); */
 }

原文地址:https://www.cnblogs.com/zcy9838/p/11639293.html

时间: 2024-08-07 01:25:23

基于node.js的express框架的图书管理功能(2)的相关文章

基于Node.js和express的日志服务器

首先,这篇文章学习的意义大于实际价值.如果按我的本意,直接在游戏中加入友盟,信息更全,而且非常简单.不过总是有很多人会凭着自己过时或者错误的经验去说别的东西多么不好,自己的东西多么好.好在,我自认为学习能力非常强,解决问题的能力也非常强.真让我做一个服务器+前端,也是在兴趣之中和能力之内. 一.Node.js简介 原本javascript纯粹是一个前端语言,干的基本上是让网页更丰富更炫的事情.不过Node.js出现后,javacript成为了前后端通吃的语言.比如网易的pomelo就是基于Nod

Node.js:Express 框架

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具.使用 Express 可以快速地搭建一个完整功能的网站. Express 框架核心特性: 可以设置中间件来响应 HTTP 请求. 定义了路由表用于执行不同的 HTTP 请求动作. 可以通过向模板传递参数来动态渲染 HTML 页面. 1.安装 Express 并将其保存到依赖列表中: $ cnpm install express --save 以上命令会

基于node.js的web框架express

1.安装node.js方法: window :https://nodejs.org/en/ linux:http://www.runoob.com/nodejs/nodejs-install-setup.html Express的官网 http://www.expressjs.com.cn/ 2.安装express方法: http://www.expressjs.com.cn/starter/installing.html 3.使用express创建第一个hello world 实例 :http

基于node.js及express实现中间件,实现post、get

首先,当然是有必要的环境,安装node,这个我就不多说了. 依赖模块: "express": "^4.13.4", "request": "^2.72.0", "body-parser": "^1.13.3", 页面 $.ajax({ type: "post", url: "/api", contentType: "application

10 个最佳的 Node.js 的 MVC 框架

补充:http://nokit.org/ https://thinkjs.org/zh-cn/doc/index.html Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台, 用来方便地搭建快速的, 易于扩展的网络应用· Node.js 借助事件驱动, 非阻塞 I/O 模型变得轻量和高效, 非常适合 run across distributed devices 的 data-intensive 的实时应用· 本文介绍 10 个基于 Node.js 的 MVC 框

《基于Node.js实现简易聊天室系列之详细设计》

一个完整的项目基本分为三个部分:前端.后台和数据库.依照软件工程的理论知识,应该依次按照以下几个步骤:需求分析.概要设计.详细设计.编码.测试等.由于缺乏相关知识的储备,导致这个Demo系列的文章层次不是很清楚,索性这一章将所有的过程(前后端以及数据库)做一个介绍,下一章写完总结就OK了吧. (1)前端部分 涉及到的技术:html.css.bootstrap.jquery.jquery UI 登录/注册界面使用的是bootstrap响应式布局,即支持不同尺寸的客户端,以此提高用户的体验.在这之前

基于 Node.js + Express + mongoDB + Bootstrap 搭建的电影网站

电影网站 ?? GitHub: https://github.com/bxm0927/movie-website 此项目是基于 Node.js + Express + mongoDB + Bootstrap 搭建的电影网站. 主要功能模块: 一期:前台电影展示页.电影详情页.后台电影管理中心(电影录入.电影修改) 二期:用户登录注册注销功能.用户识别和持久化.后台用户管理中心(用户录入.用户修改).电影评论 <!-- more --> 图片预览 技术栈 [前端] HTML/CSS/JS:亘古不

Express 4.x Node.js的Web框架

为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3821150.html 本文使用node.js v0.10.28 + express 4.2.0 1 Express概述 Express 是一个简洁而灵活的node.js的MVC Web应用框架,提供一系列强大特性创建各种Web应用. Express 不对 node.js 已有的特性进行二次抽象,我们只是在它之上扩展了We

node.js高级编程|node.js 视频教程_基于node.js+Express.js+Jade+MongoDB实战开发

基于node.js+Express.js+Jade+MongoDB开发Web即时聊天系统课程讲师:幻星课程分类:前端开发适合人群:初级课时数量:36课时更新程度:完成用到技术:Node.js NPM. Express.NoSQL,MongoDB涉及项目:匿名聊天网站系统node.js视频教程:http://www.ibeifeng.com/goods-462.htmlnode.js 教程适合人群:node.js视频教程要求学员了解JavaScript,node.js入门教程适合希望更深入的学习N