Node.js连接postgreSQL并进行数据操作


Posted in Javascript onDecember 18, 2016

前言

PostgreSql是一个面向对象的关系数据库,postgis是一个基于PostgreSql的空间数据库插件,主要用于管理地理空间数据。因此在GIS领域,广泛使用PostgreSql作为空间数据库。

首先使用npm安装数据库连接模块:

npm install --save pg

连接池创建

然后代码中引入pg模块,并编写数据库配置:

var pg = require('pg');

// 数据库配置
var config = { 
 user:"postgres",
 database:"ghost",
 password:"123456",
 port:5432,

 // 扩展属性
 max:20, // 连接池最大连接数
 idleTimeoutMillis:3000, // 连接最大空闲时间 3s
}

pg模块中有两种数据库连接方式,先讲连接池模式,下面是创建连接池:

// 创建连接池
var pool = new pg.Pool(config);

传入配置后就创建好了连接池。

查询数据

查询首先创建好连接,然后调用api进行查询:

// 查询
pool.connect(function(err, client, done) { 
 if(err) {
 return console.error('数据库连接出错', err);
 }
 // 简单输出个 Hello World
 client.query('SELECT $1::varchar AS OUT', ["Hello World"], function(err, result) {
 done();// 释放连接(将其返回给连接池)
 if(err) {
 return console.error('查询出错', err);
 }
 console.log(result.rows[0].out); //output: Hello World
 });
});

输出:

Hello World

参数done是一个函数,调用这个函数可以将关闭连接(即将连接还给连接池)。

上面的是需要写回调的异步查询,可以使用ES 7中await和async(但需安装最新版本的pg,另外,需要使用7.2以上的nodejs,最好就是用最新的nodejs)优化代码,如下:

// Async & Await 方式(需 node ^7.2.1,运行时使用 node --harmony-async-await index.js)
var query = async () => { 
 // 同步创建连接
 var connect = await pool.connect()
 try {
 // 同步等待结果
 var res = await connect.query('SELECT $1::varchar AS OUT', ['Hello World By Async&Await'])
 console.log(res.rows[0].out) // 可以通过rows遍历数据
 } finally {
 connect.release()
 }
}

// 异步进行数据库处理
query().catch(e => console.error(e.message, e.stack));

在升级了nodejs之后,执行代码的时候,需要加参数--harmony-async-await

npm --harmony-async-await index.js

当然,都支持到ES7了,ES6的Promise方法肯定是支持的,如下:

pool.connect().then(client=>{ 
 client.query('SELECT $1::varchar AS OUT', ['Hello World By Promise']).then(res=>{
 client.release()
 console.log(res.rows[0].out)
 }).catch(e => {
 client.release()
 console.error('query error', e.message, e.stack)
 })
})

插入、修改、删除数据

插入、修改、删除数据和查询的差不多

// 在表test中插入、修改、删除数据,共两个字段 (name, age)
pool.connect().then(client=>{ 
 // insert 数据
 client.query("INSERT INTO test(name, age) VALUES($1::varchar, $2::int)", ["xiaoming","20"]).then(res=>{
 console.log("Insert Success")
 // 如果是自增ID,有返回值的,在res里
 return res;
 }).then(res=>{
 // 查询xiaoming
 return client.query("Select * FROM test WHERE name = $1", ["xiaoming"]);
 }).then(res=>{
 // 输出结果,看是否插入成功
 console.log(res.rows[0])
 }).then(res=>{
 // update 数据,将age改为21
 return client.query("UPDATE test SET age=$1 WHERE name=$2", [21, "xiaoming"])
 }).then(res=>{
 // 再查询一次xiaoming
 return client.query("Select * FROM test WHERE name = $1", ["xiaoming"]);
 }).then(res=>{
 // 再输出结果,看是否改为了21
 console.log(res.rows[0])
 }).then(res=>{
 // 删除数据
 client.query("DELETE FROM test WHERE name=$1", ["xiaoming"])
 }).then(res=>{
 // 最后再查询一次xiaoming
 res = client.query("Select * FROM test WHERE name = $1", ["xiaoming"]);
 // 释放连接
 client.release()
 return res
 }).then(res=>{
 // 再输出结果,没数据 undefined
 console.log(res.rows[0])
 })
})

上面插入、更新里代码都没有进行错误处理,按道理是要加的,但如果要加try...catch...的话,就太麻烦了(毕竟只是示例).

事件监听

可以添加error事件方法监听连接池情况

pool.on("error", function(err, client){ 
 console.log("error --> ", err)
})

现在连接池的最大空闲时间是3s,也就是3s还没使用连接,就释放连接,可将这个时间设置得长一些,比如30s,这就让我们有足够的时间关掉数据库进行测试(与数据库连接一断开,这个事件就被触发了,生产环境中,可以用来写日志啊、发邮件短信通知什么的。。。)。

另外,还可以监听acquire和connect事件,前者在连接被客户端获取时触发,后者在连接生成以及客户端与数据库交互时触发。

pool.on('acquire', function (client) { 
 console.log("acquire Event")
})

pool.on('connect', function () { 
 console.log("connect Event")
})

不使用连接池的客户端

不使用连接池时,直接创建客户端即可:

var client = new pg.Client();

连接池只是用来管理(缓存)连接(即客户端)的,查询之类的方法跟它没关系。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能有一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
jQuery ready函数滥用分析
Feb 16 Javascript
js自动闭合html标签(自动补全html标记)
Oct 04 Javascript
jquery实现加载等待效果示例
Sep 25 Javascript
我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环
Jul 06 Javascript
图解Sublime Text3使用技巧
Dec 21 Javascript
理解jquery事件冒泡
Jan 03 Javascript
使用jquery提交form表单并自定义action的实现代码
May 25 Javascript
VUE脚手架的下载和配置步骤详解
Apr 01 Javascript
vue解决花括号数据绑定不成功的问题
Oct 30 Javascript
vue打包npm run build时候界面报错的解决
Aug 13 Javascript
解决iView Table组件宽度只变大不变小的问题
Nov 13 Javascript
vue导入.md文件的步骤(markdown转HTML)
Dec 31 Vue.js
纯js实现悬浮按钮组件
Dec 17 #Javascript
Jquery Easyui搜索框组件SearchBox使用详解(19)
Dec 17 #Javascript
Bootstrap CSS组件之按钮下拉菜单
Dec 17 #Javascript
谈谈JS中常遇到的浏览器兼容问题和解决方法
Dec 17 #Javascript
Bootstrap CSS组件之按钮组(btn-group)
Dec 17 #Javascript
谈谈JavaScript中浏览器兼容问题的写法小议
Dec 17 #Javascript
Bootstrap CSS组件之下拉菜单(dropdown)
Dec 17 #Javascript
You might like
PHP构造二叉树算法示例
2017/06/21 PHP
在Laravel5.6中使用Swoole的协程数据库查询
2018/06/15 PHP
编写跨浏览器的javascript代码必备[js多浏览器兼容写法]
2008/10/29 Javascript
JavaScript初学者应注意的七个细节小结
2012/01/30 Javascript
jquery插件实现鼠标经过图片右侧显示大图的效果(类似淘宝)
2013/02/04 Javascript
jquery取消选择select下拉框示例代码
2014/02/22 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
2014/08/12 Javascript
通过JS动态创建一个html DOM元素并显示
2014/10/15 Javascript
jquery实现的仿天猫侧导航tab切换效果
2015/08/24 Javascript
基于jQuery插件实现点击小图显示大图效果
2016/05/11 Javascript
js字符串截取函数slice、substring和substr的比较
2016/05/17 Javascript
JavaScript 继承详解(六)
2016/10/11 Javascript
随机生成10个不重复的0-100的数字(实例讲解)
2017/08/16 Javascript
微信小程序 获取javascript 里的数据
2017/08/17 Javascript
详解react关于事件绑定this的四种方式
2018/03/09 Javascript
jQuery对底部导航进行跳转并高亮显示的实例代码
2019/04/23 jQuery
Angular8路由守卫原理和使用方法
2019/08/29 Javascript
vue在路由中验证token是否存在的简单实现
2019/11/11 Javascript
基于openlayers实现角度测量功能
2020/09/28 Javascript
9个JavaScript日常开发小技巧
2020/10/06 Javascript
盘点提高 Python 代码效率的方法
2014/07/03 Python
Python探索之Metaclass初步了解
2017/10/28 Python
解决已经安装requests,却依然提示No module named requests问题
2018/05/18 Python
浅谈dataframe中更改列属性的方法
2018/07/10 Python
基于python中theano库的线性回归
2018/08/31 Python
Django集成celery发送异步邮件实例
2019/12/17 Python
Python使用正则实现计算字符串算式
2019/12/29 Python
pytorch实现onehot编码转为普通label标签
2020/01/02 Python
解决PyCharm无法使用lxml库的问题(图解)
2020/12/22 Python
美国高端医师级美容产品电商:BeautifiedYou.com
2017/04/17 全球购物
英文请假条
2014/04/11 职场文书
好的旅游活动方案
2014/08/19 职场文书
校园主题婚礼活动策划方案
2014/09/15 职场文书
基于angular实现树形二级表格
2021/10/16 Javascript
解决 Redis 秒杀超卖场景的高并发
2022/04/12 Redis
Python内置的数据类型及使用方法
2022/04/13 Python