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 相关文章推荐
FLASH 广告之外的链接
Dec 16 Javascript
JQUERY操作JSON实例代码
Feb 09 Javascript
BOM与DOM的区别分析
Oct 26 Javascript
21个JavaScript事件(Events)属性汇总
Dec 02 Javascript
推荐6款基于jQuery实现图片效果插件
Dec 07 Javascript
Jquery常用的方法汇总
Sep 01 Javascript
Bootstrap3制作搜索框样式的方法
Jul 11 Javascript
Vuejs第七篇之Vuejs过渡动画案例全面解析
Sep 05 Javascript
简单理解Vue条件渲染
Dec 03 Javascript
jquery validation验证表单插件
Jan 07 Javascript
微信小程序 图片加载(本地,网路)实例详解
Mar 10 Javascript
node.js使用mongoose操作数据库实现购物车的增、删、改、查功能示例
Dec 23 Javascript
基于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操作sqlserver关于时间日期读取的小小见解
2009/11/29 PHP
file_get_contents获取不到网页内容的解决方法
2013/03/07 PHP
PHP mysql与mysqli事务使用说明 分享
2013/08/17 PHP
PHP中file_exists()判断中文文件名无效的解决方法
2014/11/12 PHP
浅谈PHP中Stream(流)
2015/06/08 PHP
php数组合并与拆分实例分析
2015/06/12 PHP
详解WordPress开发中get_header()获取头部函数的用法
2016/01/08 PHP
PDO::prepare讲解
2019/01/29 PHP
nodejs入门详解(多篇文章结合)
2012/03/07 NodeJs
JavaScript 上万关键字瞬间匹配实现代码
2013/07/07 Javascript
原生js实现模拟滚动条
2015/06/15 Javascript
Javascript技术栈中的四种依赖注入详解
2016/02/23 Javascript
Jquery实现简单的轮播效果(代码管用)
2016/03/14 Javascript
基于jQuery和Bootstrap框架实现仿知乎前端动态列表效果
2016/11/09 Javascript
react开发中如何使用require.ensure加载es6风格的组件
2017/05/09 Javascript
angularjs数组判断是否含有某个元素的实例
2018/02/27 Javascript
快速解决Vue项目在IE浏览器中显示空白的问题
2018/09/04 Javascript
vue的for循环使用方法
2019/02/12 Javascript
浅谈js闭包理解
2019/03/28 Javascript
实例详解vue中的$root和$parent
2019/04/29 Javascript
JS代码简洁方式之函数方法详解
2020/07/28 Javascript
python代码制作configure文件示例
2014/07/28 Python
python中MySQLdb模块用法实例
2014/11/10 Python
编写Python脚本使得web页面上的代码高亮显示
2015/04/24 Python
Python cx_freeze打包工具处理问题思路及解决办法
2016/02/13 Python
Python设计模式之抽象工厂模式
2016/08/25 Python
Python内建模块struct实例详解
2018/02/02 Python
使用Python来做一个屏幕录制工具的操作代码
2020/01/18 Python
Python如何避免文件同名产生覆盖
2020/06/09 Python
英国的知名精品百货公司:House of Fraser(福来德)
2016/08/14 全球购物
西班牙在线光学:Visual-Click
2020/06/22 全球购物
一年级家长会邀请函
2014/01/25 职场文书
小学校本教研总结
2015/08/13 职场文书
golang 接口嵌套实现复用的操作
2021/04/29 Golang
关于redisson缓存序列化几枚大坑说明
2021/08/04 Redis
spring 项目实现限流方法示例
2022/07/15 Java/Android