|||
前5篇博文,分别写了使用PG的JSONB类型的几个方面:
这一篇写写Node.js如何方便的使用PostgreSQL中的JSONB数据,为什么要写Node.js呢(可能很多人还没使用过),这是有原因的,我们先来看Josh Berkus(他是谁?https://www.postgresql.org/community/contributors/ ,第1个人 )写的一篇博文, Why HStore2/jsonb is the most important patch of 9.4 :
Open source databases rise and fall on the popularity of the programming languages which use those databases. ... While the future is unpredictable, the current momentum in programming languages is behind two platforms: Node.js and Go. PostgreSQL already enjoys good support and adoption among Go users. However, our adoption in the Node.js community is less encouraging.
If you've watched database adoption trends for the last 20 years like I have, this is alarming. We are in danger of being sidelined.... What do Node.js users want that we don't have? There's three main things that I've been able to identify:
|
这里摘录了大片的原文,因为写到很到位,几乎没有废话(Leader都是这样的吗?),一看乔什小伙子就很有商业头脑(价值思维+竞争者思维),总而言之,一句话,适者生存,PG也是世界中的一员,也要寻求生存空间。
那 Node.js 究竟是什么?请看看这里:http://www.ibm.com/developerworks/cn/opensource/os-nodejs/index.html?ca=drs#ibm-pcon 。这里摘录一句话:
它对什么有好处? 正如您此前所看到的,Node 非常适合以下情况:在响应客户端之前,您预计可能有很高的流量,但所需的服务器端逻辑和处理不一定很多。Node 表现出众的典型示例包括: RESTful API 提供 RESTful API 的 Web 服务接收几个参数,解析它们,组合一个响应,并返回一个响应(通常是较少的文本)给用户。这是适合 Node 的理想情况,因为您可以构建它来处理数万条连接。它仍然不需要大量逻辑;它本质上只是从某个数据库中查找一些值并将它们组成一个响应。由于响应是少量文本,入站请求也是少量的文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的 API 需求。 |
其实,我觉得最重要的理由是,现在客户端PC Web+APP+微信编程都用H5(css3/js/ionic/jquery/websocket/framework7/react/bootstrap),服务端编程为何不也用H5里的js呢,反正开发语言都熟悉,干嘛用JAVA? 而且最最重要的是RESTful API的风格并不要求服务端编程花费大量的精力呀,大都是增删改查数据库,没有以往2B业务复杂的中间层业务逻辑,一学就会,干嘛去看别人脸色学习复杂的J2EE/PHP/.NET。而且老板也喜欢呀,一个前端程序员搞定前端、Node.js、数据库,多省钱,以前至少是2倍或3倍以上的成本呀。
我一定要把上面的字体加黑变红,才显得这段话是多么重要,你甭管Node.js一大堆的劣势,时代变了,2c业务+js包打天下+RESTful API三大宇宙最强好声音(别只看 中国好声音),于是乎Node.js也就这么火起来了,http://www.google.cn/trends/explore#q=%2Fm%2F0bbxf89%2C%20json&cmpt=q&tz=Etc%2FGMT-8 , 看下图:
Node.js和JSON几乎是从2009年以后就携手同行了,所以,我们还是要写写 Node.js+JSON+PostgreSQL 三兄弟的量子纠缠态。
开发环境:
1. Node.js入门,如何写Restful API
Manuel(http://manuel.manuel.net/)写的http://www.nodebeginner.org/index-zh-cn.html 简直就是经典(我学习的榜样),花1个小时了解Node.js入门。
然后再花1个小时看看 Designing a RESTful API With Node and Postgres 如何用Node.js+PostgreSQL实现Restful API(下一节我们将使用这个例子)。
或者再看看: http://mherman.org/blog/2015/02/12/postgresql-and-nodejs/#.WA1oYfl96Uk
2. Node.js如何使用PG的JSONB
我们使用上面 Designing a RESTful API With Node and Postgres 里面的例子( Node.js, express-generator, pg-promise , PostgreSQL v9.6, and Bluebird),然后使用PG中JSONB存储和访问效率(PG JSON系列5)中的第2类表做实验(第1类表类似):
-- Table: R_PIC_PERSON_JSONB_USEARRAY -- 照片中的人的信息表,用JSONB实现,JSONB数组形式,即一行对应普通表的多行 DROP TABLE IF EXISTS R_PIC_PERSON_JSONB_USEARRAY CASCADE; CREATE TABLE R_PIC_PERSON_JSONB_USEARRAY ( id serial,-- 照片id persons jsonb NOT NULL -- 格式为:[{"position":"前1排左1","name":"张晓陆","phone":"18910180100","city":"济南","organization":"中科院计算所","attendanceYear":2012,"graduationYear":2016},{"position":"前1排左2","name":"张晓陆","phone":"18910180100","organization":"中科院计算所","attendanceYear":2012,"graduationYear":2016}] )WITH (OIDS=FALSE); |
测试数据:
insert into R_PIC_PERSON_JSONB_USEARRAY values (1, '[{"position":"前1排左1","name":"张晓陆","phone":"18910180100","city":"济南","organization":"中科院计算所","attendanceYear":2012,"graduationYear":2016}, {"position":"前1排左2","name":"张晓陆2","phone":"18910180100","organization":"中科院计算所","attendanceYear":2012,"graduationYear":2016}]' ); |
好,我们来设计如下RESTful API:
URLHTTP Verb Action /api/pic/persons GET 返回该图片中的所有人,需要传入参数:图片的id /api/pic/person/:idx GET 返回图片中第idx个人 /api/pic/persons POST 增加一个人 /api/pic/person/:idx PUT 更新一个人 /api/pic/person/:idx DELETE 删除一个人 |
然后在index.js里增加路由:
router.get('/api/pic/persons', db.getPicAllPersons); router.get('/api/pic/person/:idx', db.getPicSinglePerson); router.post('/api/pic/persons', db.createPicPerson); router.put('/api/pic/person/:idx', db.updatePicPerson); router.delete('/api/pic/person/:idx', db.removePicPerson); |
在queries.js里增加处理函数:
function getPicAllPersons(req, res, next) { var picID = parseInt(req.query.id); db.one('select * from R_PIC_PERSON_JSONB_USEARRAY where id = $1', picID) .then(function (data) { res.status(200) .json({ status: 'success', data: data, message: 'Retrieved ALL persons in a pic' }); }) .catch(function (err) { return next(err); }); } |
上面的req.query.id是指图片的id,用Postman测试结果如下:
然后,
function getPicSinglePerson(req, res, next) { var personIdx = parseInt(req.params.idx); var picID = parseInt(req.query.id); db.one('select a.id,a.persons->$1 as person from R_PIC_PERSON_JSONB_USEARRAY a where a.id = $2', [personIdx,picID]) .then(function (data) { res.status(200) .json({ status: 'success', data: data, message: 'Retrieved ONE PERSON' }); }) .catch(function (err) { return next(err); }); } |
通过http://localhost:3000/api/pic/person/1?id=1 测试一下, 返回结果为:
{"status":"success","data":{"id":1,"person":{"name":"张晓陆2","phone":"18910180100","position":"前1排左2","organization":"中科院计算所","attendanceYear":2012,"graduationYear":2016}},"message":"Retrieved ONE PERSON"}
然后是 router.post('/api/pic/persons', db.createPicPerson); 的处理函数:
function createPicPerson(req, res, next) { var aPersonJson = req.body; var picID = parseInt(req.query.id); db.none('update R_PIC_PERSON_JSONB_USEARRAY set persons = persons || $1 where id = $2',[aPersonJson,picID]) .then(function () { res.status(200) .json({ status: 'success', message: 'Inserted one person' }); }) .catch(function (err) { return next(err); }); } |
用Postman测试结果如下:
剩下的
router.put('/api/pic/person/:idx', db.updatePicPerson);
router.delete('/api/pic/person/:idx', db.removePicPerson);
我就不写了,大家当作练习吧。
结论:在Node.js里结合express-generator, pg-promise访问pg的JSONB类型和普通的访问数据库没什么异同,当然好处是直接可以把客户端POST传入的json对象灌入到PG中,以及从PG中直接返回JSON串,而在Node.js层面只是做简单的封装转发。
参考:
Why HStore2/jsonb is the most important patch of 9.4, http://www.databasesoup.com/2014/02/why-hstore2jsonb-is-most-important.html
http://blog.j0.hn/post/48591247017/using-json-in-postgres-and-nodejs
http://www.ibm.com/developerworks/cn/opensource/os-nodejs/index.html?ca=drs#ibm-pcon
https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4
https://medium.com/@jeffandersen/building-a-node-js-rest-api-with-express-46b0901f29b6#.t9s9w02j6
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
码字码了半天,手指头都麻了,如果觉得对您还有用的话,赞助一下辛苦费吧:
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-11-23 20:01
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社