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 相关文章推荐
云网广告中的代码,提示出错,大家找找
Nov 21 Javascript
JQuery 入门实例1
Jun 25 Javascript
js判断undefined变量类型使用typeof
Jun 03 Javascript
网站404页面3秒后跳到首页的实例代码
Aug 16 Javascript
火狐下table中创建form导致两个table之间出现空白
Sep 02 Javascript
JScript分割字符串示例代码
Sep 04 Javascript
快速解决jQuery与其他库冲突的方法介绍
Jan 02 Javascript
Angular 4依赖注入学习教程之简介(一)
Jun 04 Javascript
解决Layui 表单提交数据为空的问题
Aug 15 Javascript
JS打印彩色菱形的实例代码
Aug 15 Javascript
关于layui时间回显问题的解决方法
Sep 24 Javascript
正则表达式基础与常用验证表达式
Jun 16 Javascript
纯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脚本代码
2011/02/19 PHP
PHP取整数函数常用的四种方法小结
2012/07/05 PHP
利用php实现禁用IE和火狐的缓存问题
2012/12/03 PHP
推荐十款免费 WordPress 插件
2015/03/24 PHP
php强制下载文件函数
2016/08/24 PHP
加载列表时jquery获取ul中第一个li的属性
2014/11/02 Javascript
浅谈JavaScript 框架分类
2014/11/10 Javascript
Javascript中typeof 用法小结
2015/05/12 Javascript
跟我学习javascript解决异步编程异常方案
2015/11/23 Javascript
JS控制伪元素的方法汇总
2016/04/06 Javascript
Jquery和BigFileUpload实现大文件上传及进度条显示
2016/06/27 Javascript
详解AngularJS如何实现跨域请求
2016/08/22 Javascript
详解小程序毫秒级倒计时(适用于拼团秒杀功能)
2019/05/05 Javascript
js实现页面多个日期时间倒计时效果
2019/06/20 Javascript
微信小程序引入VANT组件的方法步骤
2019/09/19 Javascript
原生JavaScript实现日历功能代码实例(无引用Jq)
2019/09/23 Javascript
javascript实现倒计时关闭广告
2021/02/09 Javascript
Python中使用中文的方法
2011/02/19 Python
详解Python中for循环的使用
2015/04/14 Python
编写Python脚本批量下载DesktopNexus壁纸的教程
2015/05/06 Python
使用Python实现简单的服务器功能
2017/08/25 Python
在django中自定义字段Field详解
2019/12/03 Python
pycharm-professional-2020.1下载与激活的教程
2020/09/21 Python
基于Python采集爬取微信公众号历史数据
2020/11/27 Python
HTML5轻松实现全屏视频背景的示例
2018/04/23 HTML / CSS
FILA斐乐中国官方商城:意大利运动品牌
2017/01/25 全球购物
YSL Beauty加拿大官方商城:圣罗兰美妆加拿大
2017/05/15 全球购物
Lampegiganten丹麦:欧洲领先的照明网上商店
2018/04/25 全球购物
惠普新加坡官方商店:HP Singapore
2020/04/17 全球购物
设计部经理的岗位职责
2013/11/16 职场文书
社区两委对照检查材料
2014/08/23 职场文书
入党积极分子学习优秀共产党员先进事迹思想汇报
2014/09/13 职场文书
歌剧魅影观后感
2015/06/05 职场文书
Python实现信息轰炸工具(再也不怕说不过别人了)
2021/06/11 Python
关于nginx 实现jira反向代理的问题
2021/09/25 Servers
Oracle中日期的使用方法实例
2022/07/07 Oracle