相关推荐recommended
Node.js 连接 mysql 数据库
作者:mmseoamin日期:2024-01-18

目录

一、安装驱动

二、连接数据

1、数据库连接的配置信息

数据库连接参数说明

2、封装 mysql 的执行语句

3、后端路由文件 

三、数据库操作( CURD )

1、查询数据

2、插入数据

3、更新数据

4、删除数据

4、获取受影响的行数

5、获取更改的行数

6、多语句查询

7、事务

四、Exception Safety 类型重铸

五、具体操作演示

入口文件

后端路由文件

数据库配置文件 

封装 mysql 查询函数

启动项目

六、查看数据库

七、调用接口

参考文档


一、安装驱动

npm install mysql
npm install --save mysql2

mysql的兼容升级npm包mysql2,mysql2兼容mysql的api语法。

使用起来没有太大的差别,但是mysql2在性能上面提升很大。

 

二、连接数据库

1、数据库连接的配置信息

// db.config.js
// 数据库连接配置
module.exports = {
	mysql: {
		host: 'localhost', // 主机地址 (默认:localhost)
		user: 'root', // 数据库用户名
		password: 'root', // 数据库密码
		database: 'schoolmarket', // 数据库名
		port: '3306' // 端口号 (默认:3306)
	}
}

数据库连接参数说明

参数描述
host主机地址 (默认:localhost)
  user用户名
  password密码
  port端口号 (默认:3306)
  database数据库名
  charset连接字符集(默认:'UTF8_GENERAL_CI',注意字符集的字母都要大写)
  localAddress此IP用于TCP连接(可选)
  socketPath连接到unix域路径,当使用 host 和 port 时会被忽略
  timezone时区(默认:'local')
  connectTimeout连接超时(默认:不限制;单位:毫秒)
  stringifyObjects是否序列化对象
  typeCast是否将列值转化为本地JavaScript类型值 (默认:true)
  queryFormat自定义query语句格式化方法
  supportBigNumbers数据库支持bigint或decimal类型列时,需要设此option为true (默认:false)
  bigNumberStringssupportBigNumbers和bigNumberStrings启用 强制bigint或decimal列以JavaScript字符串类型返回(默认:false)
  dateStrings强制timestamp,datetime,data类型以字符串类型返回,而不是JavaScript Date类型(默认:false)
  debug开启调试(默认:false)
  multipleStatements是否许一个query中有多个MySQL语句 (默认:false)
  flags用于修改连接标志
  ssl使用ssl参数(与crypto.createCredenitals参数格式一至)或一个包含ssl配置文件名称的字符串,目前只捆绑Amazon RDS的配置文件

 

2、封装 mysql 的执行语句

// db.js
// 使用mysql2
const mysql = require('mysql2');
// 引入mysql配置文件
const dbConfig = require('./db.config');
module.exports = {
    query: function(sql, params, callback) {
        // 每次使用的时候需要创建链接,数据操作完成之后要关闭连接
        const connection = mysql.createConnection(dbConfig)
        connection.connect(function(err) {
            if (err) {
                throw err
            }
            // 执行数据操作
            connection.query(sql, params, function(err, results, fields) {
                if (err) {
                    throw err
                }
                // 将查询出来的数据返回给回调函数
                callback &&
                    callback(
                        results ? JSON.parse(JSON.stringify(results)) : null,
                        fields ? JSON.parse(JSON.stringify(fields)) : null
                    )
                // 停止链接数据库,必须在查询语句后,不然一调用这个方法,就直接停止链接,数据操作就会失败
                connection.end(function(err) {
                    if (err) {
                        console.log('关闭数据库连接失败!')
                        throw err
                    }
                })
            })
        })
    },
}

3、后端路由文件 

// 引入数据库封装对象
var db = require('./db.js');
// 引入express包
var express = require('express');
//创建路由器对象
var router = express.Router();
// 配置路由对象
router.get('/userList', (req, res, next) => {
    // sql查询user表
    db.query('select * from list', [], function(results, fields) {
        // 以json的形式返回
        res.json({ results })
    })
})

 

三、数据库操作( CURD )

1、查询数据

connection.query('SELECT * FROM `books` WHERE `author` = "David"', function (error, results, fields) {
       if(error){
          console.log('[SELECT ERROR] - ',error.message);
          return;
       }
 
       console.log('--------------------------SELECT----------------------------');
       console.log(results);
       console.log('------------------------------------------------------------\n\n');  
});
connection.query('SELECT * FROM `books` WHERE `author` = ?', ['David'], function (error, results, fields) {
       if(error){
          console.log('[SELECT ERROR] - ',error.message);
          return;
       }
 
       console.log('--------------------------SELECT----------------------------');
       console.log(results);
       console.log('------------------------------------------------------------\n\n');  
});

2、插入数据

var  addSql = 'INSERT INTO websites(Id, name, url, alexa, country) VALUES(0,?,?,?,?)';
var  addSqlParams = ['菜鸟', 'https://xxx.com','23453', 'CN'];
// 执行插入数据
connection.query(addSql,addSqlParams,function (err, result) {
        if(err){
         console.log('[INSERT ERROR] - ',err.message);
         return;
        }        
 
       console.log('--------------------------INSERT----------------------------');
       //console.log('INSERT ID:',result.insertId);        
       console.log('INSERT ID:',result);        
       console.log('-----------------------------------------------------------------\n\n');  
});

3、更新数据

var modSql = 'UPDATE websites SET name = ?,url = ? WHERE Id = ?';
var modSqlParams = ['菜鸟', 'https://xxx.com', 6];
// 更新数据
connection.query(modSql,modSqlParams,function (err, result) {
  if(err){
      console.log('[UPDATE ERROR] - ',err.message);
      return;
  }        
  console.log('--------------------------UPDATE----------------------------');
  console.log('UPDATE affectedRows', result.affectedRows);
  console.log('-----------------------------------------------------------------\n\n');
});

4、删除数据

var delSql = 'DELETE FROM websites where id=6';
// 删除数据
connection.query(delSql, function (err, result) {
        if(err){
          console.log('[DELETE ERROR] - ',err.message);
          return;
        }        
 
       console.log('--------------------------DELETE----------------------------');
       console.log('DELETE affectedRows', result.affectedRows);
       console.log('-----------------------------------------------------------------\n\n');  
});

4、获取受影响的行数

// 从插入、更新或删除语句中获取受影响的行数
connection.query('DELETE FROM posts WHERE title = "wrong"', function (error, results, fields) {
  if (error) throw error;
  console.log('deleted ' + results.affectedRows + ' rows');
})

5、获取更改的行数

// 从更新语句中获取更改的行数
// changedRows与affectedRows的不同之处在于,值未更改的更新行不被列入changedRows
connection.query('UPDATE posts SET ...', function (error, results, fields) {
  if (error) throw error;
  console.log('changed ' + results.changedRows + ' rows');
})

6、多语句查询

// 多语句查询会被SQL注入,如果确定想使用可以开启
var connection = mysql.createConnection({
    multipleStatements: true
});

7、事务

// 开启一个简单的事务
connection.beginTransaction(function(err) {
  if (err) { throw err; }
  connection.query('INSERT INTO posts SET title=?', title, function (error, results, fields) {
    if (error) {
      return connection.rollback(function() {
        throw error;
      });
    }
 
    var log = 'Post ' + results.insertId + ' added';
 
    connection.query('INSERT INTO log SET data=?', log, function (error, results, fields) {
      if (error) {
        return connection.rollback(function() {
          throw error;
        });
      }
      connection.commit(function(err) {
        if (err) {
          return connection.rollback(function() {
            throw err;
          });
        }
        console.log('success!');
      });
    });
  });
});

 

四、Exception Safety 类型重铸

默认情况下,驱动程序会将 mysql 类型转换为原生 JavaScript 类型。

mysqljavascript
TINYINTNumber
SMALLINT
INT
MEDIUMINT
YEAR
FLOAT
DOUBLE
TIMESTAMPDate
DATE
DATETIME
TINYBLOBBuffer
MEDIUMBLOB
LONGBLOB
BLOB
BINARY
VARBINARY
BIT (last byte will be filled with 0 bits as necessary)
charString
varchar
tinytext
mediumtext
longtext
text
enum
set
decimal
bigint
time
geometry

五、具体操作演示

使用 express-generator 来快速搭建一个项目

 

入口文件

// index.js
const userApi = require('./api/myApi');
const fs = require('fs');
const path = require('path');
// body-parser - node.js 中间件,用于处理 JSON, Raw, Text 和 URL 编码的数据
const bodyParser = require('body-parser');
// 引入express包
const express = require('express');
// 创建web服务器
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
// 后端api路由
app.use('/api/user', userApi);
// 监听端口
app.listen(3000);
console.log('success listen at port: 3000......');

后端路由文件

// api.js
// 引入封装 mysql 查询函数
var db = require('./db');
// 引入express包
var express = require('express');
// 创建路由器对象
var router = express.Router();
// Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件
var multer = require('multer');
// 格式化时间模块Silly-datetime
var datetime = require('silly-datetime');
var fs = require('fs');
var path = require('path')
var UUID = require('uuid')
// multer 自定义存储的方式
var storage = multer.diskStorage({  
    // 保存路径
    destination: function (req, file, cb) {
        // 注意这里的文件路径,不是相对路径,直接填写从项目根路径开始写就行了
        cb(null, 'static/public/uploads')  
    },  
    // 保存在 destination 中的文件名
    filename: function (req, file, cb) {  
        var str = file.originalname.split('.');  
        cb(null, UUID.v1() + '.' + str[1]);  
    }  
})
var upload = multer({storage: storage})
// 设置返回response
var jsonWrite = function (res, ret) {
    if (typeof ret === 'undefined') {
        res.json({
            code: '1',
            msg: '操作失败'
        });
    } else {
        console.log('ret', ret)
        res.json(ret);
    }
};
// 增加用户接口
router.post('/addUser', (req, res) => {
  let params = req.body;
  db.query("select * from user where user_id=?", [params.id], function (err, result) {
    if (err) {
      console.log(err);
    }
    if (result) {
      if (result.length > 0) {
        jsonWrite(res, {
          code: -1,
          msg: '该账号已注册!'
        });
      } else {
        db.query("INSERT INTO user(user_id,user_nick,gender,password) VALUES(?,?,?,?)", [params.id, params.nick, params.gender, params.password], function (err, result) {
          if (err) {
            console.log(err);
          }
          if (result) {
            jsonWrite(res, {
              code: 200,
              msg: '注册用户成功!'
            });
          }
        })
      }
    }
  })
});

数据库配置文件 

// db.config.js
// 数据库连接配置
module.exports = {
	mysql: {
		host: 'localhost', // 主机地址 (默认:localhost)
		user: 'root', // 数据库用户名
		password: 'root', // 数据库密码
		database: 'schoolmarket', // 数据库名
		port: '3306' // 端口号 (默认:3306)
	}
}

封装 mysql 查询函数

// db.js
// 使用mysql2
const mysql = require('mysql2');
// 引入mysql配置文件
const dbConfig = require('./db.config');
module.exports = {
    query: function(sql, params, callback) {
        // 每次使用的时候需要创建链接,数据操作完成之后要关闭连接
        const connection = mysql.createConnection(dbConfig)
        connection.connect(function(err) {
            if (err) {
                throw err
            }
            // 执行数据操作
            connection.query(sql, params, function(err, results, fields) {
                if (err) {
                    throw err
                }
                // 将查询出来的数据返回给回调函数
                callback &&
                    callback(
                        results ? JSON.parse(JSON.stringify(results)) : null,
                        fields ? JSON.parse(JSON.stringify(fields)) : null
                    )
                // 停止链接数据库,必须在查询语句后,不然一调用这个方法,就直接停止链接,数据操作就会失败
                connection.end(function(err) {
                    if (err) {
                        console.log('关闭数据库连接失败!')
                        throw err
                    }
                })
            })
        })
    },
}

 

启动项目

server是入口文件 index.js 的文件夹的名字

node server

六、查看数据库

可以使用 navicat premium 等数据库可视化工具进行查看操作数据库。

七、调用接口

可以使用浏览器或 postman 来调用接口查看返回的情况。

参考文档

Node.js 连接 MySQL | 菜鸟教程

mysql - npm

mysql2 - npm