node.js中 mysql 增删改查操作及async,await处理实例分析


Posted in Javascript onFebruary 11, 2020

本文实例讲述了node.js中 mysql 增删改查操作及async,await处理。分享给大家供大家参考,具体如下:

要对mysql进行操作,我们需要安装一个mysql的库。

一、安装mysql库

npm install mysql --save

二、对mysql进行简单查询操作

const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
  //主机地址
  host: '127.0.0.1',
  //用户名
  user: 'root',
  //密码
  password: '123456',
  //数据库
  database: 'test',
  //端口
  port: 3306,
  //字符集
  charset: 'utf8'
});
//连接数据库
conn.connect(function (err) {
  if (err) {
    throw err;
  }
  console.log('连接成功');
});
//查询数据库
conn.query('select * from tb_user', function (err, data, field) {
  if (err) {
    throw err;
  }
  //data表示结果集数据,是一个数组
  console.log(data);
  data.forEach(function (value) {
    console.log(value.id, value.user_name, value.addr);
  });
  //表字段的详细信息
  console.log(field);
});
//关闭数据库连接
conn.end();

二、对mysql进行增删改操作

const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
  //主机地址
  host: '127.0.0.1',
  //用户名
  user: 'root',
  //密码
  password: '123456',
  //数据库
  database: 'test',
  //端口
  port: 3306,
  //字符集
  charset: 'utf8'
});
//连接数据库
conn.connect(function (err) {
  if (err) {
    throw err;
  }
  console.log('连接成功');
});
//插入数据,query()方法可以对sql语句进行参数绑定,用?号作为占位符。
conn.query('insert into tb_user values(null, ?, ?)', ['xxx', 'xxx'], function (err, data) {
  if (err) {
    throw err;
  }
  if (data && data.affectedRows) {
    console.log('插入数据成功,id为', data.insertId);
  }
});
//修改数据
conn.query('update tb_user set user_name = ? where id = ?', ['ggg', 7], function (err, data) {
  if (err) {
    throw err;
  }
  if (data && data.affectedRows) {
    console.log('修改数据成功');
  }
});
//删除数据
conn.query('delete from tb_user where id = ?', [5], function (err, data) {
  if (err) {
    throw err;
  }
  if (data && data.affectedRows) {
    console.log('删除数据成功');
  }
});
//关闭数据库连接
conn.end();

三、使用mysql连接池来优化对数据库的操作

频繁的连接和断开mysql是比较消耗资源的,我们可以创建一个连接池,复用连接池中的连接,提高效率。

const mysql = require('mysql');
//创建数据库连接池
let pool = mysql.createPool({
  //连接数量,默认是10
  connectionLimit: 20,
  //主机地址
  host: '127.0.0.1',
  //用户名
  user: 'root',
  //密码
  password: '123456',
  //数据库
  database: 'test',
  //端口
  port: 3306,
  //字符集
  charset: 'utf8'
});
//pool.query()方法可以自动的帮我们在连接池中获取可用连接
pool.query('select * from tb_user', function (err, data) {
  if (err) {
    throw err;
  }
  data.forEach(function (value) {
    console.log(value.id, value.user_name, value.addr);
  });
});
//当然我们也可以手动获取可用连接
pool.getConnection(function (err, conn) {
  if (err) {
    throw err;
  }
  conn.query('select * from `order`', function (err, data) {
    if (err) {
      throw err;
    }
    data.forEach(function (value) {
      console.log(value.id, value.order_id, value.user_id);
    });
    //连接用完之后,需要释放,重新放回连接池中。
    //注意这里并没有销毁该连接,该连接仍然可用,但需要重新获取
    conn.release();
  });
});
//从连接池中获取连接时,将触发该事件
pool.on('acquire', function (conn) {
  console.log('获取连接', conn.threadId);
});
//在连接池中建立新连接时,将触发该事件
pool.on('connection', function (conn) {
  console.log('建立新连接', conn.threadId);
});
//等待可用连接时,将触发该事件
pool.on('enqueue', function () {
  console.log('等待可用连接');
});
//当连接释放回池中时,触发该事件
pool.on('release', function (conn) {
  console.log('连接被释放回池中', conn.threadId);
});
//结束池中所有的连接,不然node.js的事件循环会一直保持
setTimeout(function () {
  pool.end(function (err) {
    console.log('关闭连接池');
    console.log(err);
  });
}, 3000);

四、按流的方式进行查询

const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
  //主机地址
  host: '127.0.0.1',
  //用户名
  user: 'root',
  //密码
  password: '123456',
  //数据库
  database: 'test',
  //端口
  port: 3306,
  //字符集
  charset: 'utf8'
});
let query = conn.query('select * from tb_user');
//Query类继承自Sequence,而Sequence继承自EventEmitter
//所以Query类的实例是可以监听事件
//发生错误时
query.on('error', function (err) {
  console.log(err);
});
//获取查询字段信息
query.on('fields', function (fields) {
  console.log(fields);
});
//获取查询结果
query.on('result', function (result) {
  //暂停获取结果
  conn.pause();
  //跟流的pause()和resume()很类似,控制获取数据的频率。
  setTimeout(function () {
    console.log(result);
    //恢复获取结果
    conn.resume();
  }, 1000);
});
//查询结束
query.on('end', function () {
  console.log('查询结束');
});
conn.end();

通过query.stream()方法返回一个可读流来获取数据

const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
  //主机地址
  host: '127.0.0.1',
  //用户名
  user: 'root',
  //密码
  password: '123456',
  //数据库
  database: 'test',
  //端口
  port: 3306,
  //字符集
  charset: 'utf8'
});
//从一个查询中获取一个可读流
let qs = conn.query('select * from tb_user').stream({highWaterMark: 2});
let result = [];
qs.on('data', function (data) {
  result.push(data);
});
qs.on('end', function () {
  console.log('查询结束');
  console.log(result);
});
conn.end();

五、mysql的事务处理

const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
  //主机地址
  host: '127.0.0.1',
  //用户名
  user: 'root',
  //密码
  password: '123456',
  //数据库
  database: 'test',
  //端口
  port: 3306,
  //字符集
  charset: 'utf8'
});
//连接数据库
conn.connect(function (err) {
  if (err) {
    throw err;
  }
  console.log('连接成功');
});
//开启一个事务
conn.beginTransaction(function (err) {
  if (err) {
    throw err;
  }
  conn.query('update account set money = money - 50 where name = ?', ['A'], function (err, data) {
    if (err) {
      //如果有错误则回滚
      return conn.rollback(function () {
        throw err;
      });
    }
    conn.query('update account set money = money + 50 where name = ?', ['B'], function (err, data) {
      if (err) {
        //如果有错误则回滚
        return conn.rollback(function () {
          throw err;
        });
      }
      //提交事务
      conn.commit(function (err) {
        if (err) {
          //如果有错误则回滚
          return conn.rollback(function () {
            throw err;
          });
        }
        console.log('处理成功');
        conn.end();
      });
    });
  });
});

六、解决mysql嵌套回调的问题

有些时候我们的操作需要上一个操作的结果,这样会导致比较深的嵌套问题,为了解决可以使用async和await来解决,而async和await又是基于promise的。

const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
  //主机地址
  host: '127.0.0.1',
  //用户名
  user: 'root',
  //密码
  password: '123456',
  //数据库
  database: 'test',
  //端口
  port: 3306,
  //字符集
  charset: 'utf8'
});
function query(conn, sql, params = []) {
  if (!conn) {
    return;
  }
  return new Promise(function (resolve, reject) {
    conn.query(sql, params, function (err, data) {
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}
(async function () {
  let result = await query(conn, 'select * from tb_user');
  console.log(result);
  let row = await query(conn, 'select * from tb_user where id = ?', [result[0].id]);
  console.log(row);
  conn.end();
})();

当然我们还可以使用 util.promiseify() 进行包装。

const mysql = require('mysql');
const util = require('util');
//创建数据库连接
let conn = mysql.createConnection({
  //主机地址
  host: '127.0.0.1',
  //用户名
  user: 'root',
  //密码
  password: '123456',
  //数据库
  database: 'test',
  //端口
  port: 3306,
  //字符集
  charset: 'utf8'
});
//注意通过util.promisify进行包装的函数,必须满足
//1、函数的最后一个参数是回调函数
//2、回调函数的参数为(err, result),前者是错误,后者是正常结果
//注意这里不要重新创建一个变量,不然会报错。
conn.query = util.promisify(conn.query);
(async function () {
  let result = await conn.query('select * from tb_user');
  console.log(result);
  let row = await conn.query('select * from tb_user where id = ?', [result[0].id]);
  console.log(row);
  conn.end();
})();

希望本文所述对大家node.js程序设计有所帮助。

Javascript 相关文章推荐
JQUERY 浏览器判断实现函数
Aug 20 Javascript
javascript中的float运算精度实例分析
Aug 21 Javascript
JavaScript类和继承 this属性使用说明
Sep 03 Javascript
MooTools 页面滚动浮动层智能定位实现代码
Aug 23 Javascript
Bootstrap按钮组简单实现代码
Mar 06 Javascript
Angular实现一个简单的多选复选框的弹出框指令实例
Apr 25 Javascript
Javascript实现找不同色块的游戏
Jul 17 Javascript
使用clipboard.js实现复制功能的示例代码
Oct 16 Javascript
vue.js中toast用法及使用toast弹框的实例代码
Aug 27 Javascript
微信小程序实现按字母排列选择城市功能
Nov 25 Javascript
浅谈JavaScript 声明提升
Sep 14 Javascript
Vue ​v-model相关知识总结
Jan 28 Vue.js
基于Angular 8和Bootstrap 4实现动态主题切换的示例代码
Feb 11 #Javascript
原生js实现点击轮播切换图片
Feb 11 #Javascript
node.js中process进程的概念和child_process子进程模块的使用方法示例
Feb 11 #Javascript
小程序如何定位所在城市及发起周边搜索
Feb 11 #Javascript
JS+DIV实现拖动效果
Feb 11 #Javascript
vue项目中使用particles实现粒子背景效果及遇到的坑(按钮没有点击响应)
Feb 11 #Javascript
原生js拖拽实现图形伸缩效果
Feb 10 #Javascript
You might like
php 特殊字符处理函数
2008/09/05 PHP
Warning: session_destroy() : Trying to destroy uninitialized sessionq错误
2011/06/16 PHP
thinkPHP5框架实现基于ajax的分页功能示例
2018/06/12 PHP
php如何实现数据库的备份和恢复
2020/11/30 PHP
ExtJS GTGrid 简单用户管理
2009/07/01 Javascript
WEB页子窗口(showModalDialog和showModelessDialog)使用说明
2009/10/25 Javascript
利用百度地图JSAPI生成h7n9禽流感分布图实现代码
2013/04/15 Javascript
JS.getTextContent(element,preformatted)使用介绍
2013/09/21 Javascript
javascript 实现 原路返回
2015/01/21 Javascript
第二章之Bootstrap 页面排版样式
2016/04/25 Javascript
Javascript json object 与string 相互转换的简单实现
2016/09/27 Javascript
bootstrap 设置checkbox部分选中效果
2017/04/20 Javascript
在vue-cli脚手架中配置一个vue-router前端路由
2017/07/03 Javascript
Angular+Bootstrap+Spring Boot实现分页功能实例代码
2017/07/21 Javascript
javascript实现Emrips反质数枚举的示例代码
2017/12/06 Javascript
Vue cli3 库模式搭建组件库并发布到 npm的流程
2018/10/12 Javascript
vue路由插件之vue-route
2019/06/13 Javascript
js实现开关灯效果
2020/03/30 Javascript
Python遍历指定文件及文件夹的方法
2015/05/09 Python
flask中使用蓝图将路由分开写在不同文件实例解析
2018/01/19 Python
Python面向对象之继承和组合用法实例分析
2018/08/27 Python
Pytorch mask_select 函数的用法详解
2020/02/18 Python
Python JSON常用编解码方法代码实例
2020/09/05 Python
微软开源最强Python自动化神器Playwright(不用写一行代码)
2021/01/05 Python
Lentiamo丹麦:购买便宜的隐形眼镜
2021/01/13 全球购物
中学生校园广播稿
2014/01/16 职场文书
英文求职信写作小建议
2014/02/16 职场文书
2014年文学毕业生自我鉴定
2014/04/23 职场文书
公司担保书范文
2014/05/21 职场文书
信息员培训方案
2014/06/12 职场文书
2014年幼儿园班级工作总结
2014/12/17 职场文书
紧急通知
2015/04/17 职场文书
义卖募捐活动总结
2015/05/09 职场文书
礼貌问候语大全
2015/11/10 职场文书
MongoDB balancer的使用详解
2021/04/30 MongoDB
MySQL 字符集 character
2022/05/04 MySQL