资讯专栏INFORMATION COLUMN

【Node Hero】5. Node.js 数据库教程

Hujiawei / 1749人阅读

摘要:是一种设计用于关系型数据库的查询语言。另一方面,数据库在最近十年变得相当流行。大多数数据库都有驱动程序可以用,它们在上也有库。我们已经完成了在中使用数据库所必须知道的所有基础知识。

本文转载自:众成翻译
译者:网络埋伏纪事
链接:http://www.zcfy.cc/article/1751
原文:https://blog.risingstack.com/node-js-database-tutorial/

如下的 Node.js 数据库教程将展示如何设置 Node.js 应用程序的数据库,并且教你使用它的基础知识。

将数据存储在一个全局变量中

正如在上章所学,为用户提供静态页面,可能适合着陆页或者个人博客。但是,如果想交付个性化的内容,就必须将数据存在某个地方。

举个例子:用户注册。可以为个别用户提供定制内容,或者只让它在用户通过身份验证后可用。

如果用户想注册你的应用程序,你可能想创建一个路由处理器来让他注册成功:

const users = []

app.post("/users", function (req, res) {  
    // 从请求消息体中获取用户发送的数据
    const user = req.body
    users.push({
      name: user.name,
      age: user.age
    })
    res.send("注册成功!")
})

通过这种方式,可以把用户存储在一个全局变量中,这个全局变量在应用程序生命周期都会驻留在内存中。

使用这种方式会因为几个原因而带来问题:

内存很贵,

每次重新启动应用程序时,内存都会重置,

如果不清理的话,有时候会遇到栈溢出。

将数据存储在文件中

出现在你脑海中的下一件事情可能是将数据存储在文件中。

如果把用户数据永久性地存储在文件系统中,就可以避免之前列出的问题。

实践中,这个方法看起来就像如下这样:

const fs = require("fs")

app.post("/users", function (req, res) {  
    const user = req.body
    fs.appendToFile("users.txt", JSON.stringify({ name: user.name, age: user.age }), (err) => {
        res.send("注册成功!")
    })
})

这种方式我们不会丢失用户数据,即使服务器重启后也不会。这种解决方案也是经济有效的,因为买存储空间比买内存更便宜。

不幸的是,用这种方式存储用户数据依然有几个缺陷:

添加用户数据是可以的,但是想想更新或者删除。

如果是存到文件,并行访问文件就没那么容易了(系统级锁会阻止写数据)。

当扩展应用程序时,没法把文件分割放在服务器之间(可以,但是方法超出了本教程的等级)。

这就是真实数据库起作用的地方。

你可能已经听说过数据库有两种主要类型:SQL 和 NOSQL。

SQL

我们以 SQL 开始。SQL 是一种设计用于关系型数据库的查询语言。根据正在使用的产品,SQL 有几种风格,但基本原理都是相同。

数据本身会被存储在表中,每个插入的块将会被表示为表中的一行,就像 Google Sheets 或者 Microsoft Excel 中的一样。

在一个 SQL 数据库中,你可以定义 schema - 这些 schema 会为你要放进去的数据提供一个骨架。在存储数据之前,必须设置不同值的类型。例如,必须为用户数据定义一个表,必须告诉数据库用户名是字符串类型,年龄是整型。

NoSQL

另一方面,NoSQL 数据库在最近十年变得相当流行。如果使用 NoSQL,就不需要定义 schema,可以存储任意 JSON。这对 JavaScript 很方便,因为在 JavaScript 中将对象转换为 JSON 很容易。不过,使用 NoSQL 要当心,因为它无法保证数据的一致性,也无法知道数据库中存的是什么。

Node.js 和 MongoDB

我们总会听到对 Node.js 的一个常见误解:

"Node.js 只能用 MongoDB( MongoDB 是最流行的 NoSQL 数据库)。"

根据我的经验,这是不正确的。大多数数据库都有驱动程序可以用,它们在 NPM 上也有库。据我看,它们与 MongoDB 一样简单易用。

Node.js 和 PostgreSQL

为简单起见,我们打算在下面的示例中使用 SQL。我选择的是 PostgreSQL。

要让 PostgreSQL 启动和运行,必须将它安装到你的电脑上。如果是 Mac,就用 homebrew 安装 PostgreSQL。另外,如果是 Linux,就用你用的包管理器安装它。

进一步的信息请阅读这篇优秀的指南,让你的第一个数据库启动和运行起来。

如果你打算用一种数据库浏览工具,我推荐使用命令行程序 psql - 它与 PostgreSQL 服务器安装程序绑在一起。这里有一个小速查表,如果你开始用 PostgreSQL,这玩意迟早会派上用场。

如果不喜欢命令行界面,可以用开源的 PostgreSQL 管理图形界面工具 pgAdmin。

注意,SQL 本身就是一门语言,我们不会讲解它所有功能,只会提及最简单的。要了解更多的关于 SQL 的知识,这里有不少讲解 PostgreSQL 基础知识的课程都还不错。

Node.js 数据库交互

首先,得创建要使用的数据库。为此,在终端中键入如下命令:

createdb node_hero

然后,创建用户表:

CREATE TABLE users(  
  name VARCHAR(20),
  age SMALLINT
);

最后,回到编码。如下是通过 Node.js 程序与数据交互的代码:

"use strict"

const pg = require("pg")  
const conString = "postgres://username:password@localhost/node_hero" // 确保要匹配你自己数据库的凭据

pg.connect(conString, function (err, client, done) {  
  if (err) {
    return console.error("error fetching client from pool", err)
  }
  client.query("SELECT $1::varchar AS my_first_query", ["node hero"], function (err, result) {
    done()

    if (err) {
      return console.error("error happened during query", err)
    }
    console.log(result.rows[0])
    process.exit(0)
  })
})

这是一个简单的 PostgreSQL "hello world" 示例。注意第一个参数是 SQL 命令字符串,第二个参数是给查询提供的参数值数组。

如果就按用户输入插入到数据库,会有很大的安全问题。这种方式可以防止 SQL 注入式攻击,这种类型的攻击是攻击者试图利用完全未处理的 SQL 查询。在创建任何面向用户的应用程序时,必须总要考虑这种情况。要学习更多关于 SQL 安全性的知识,请查看我们的 Node.js 应用程序安全备忘录。

下面继续前一示例。

app.post("/users", function (req, res, next) {  
  const user = req.body

  pg.connect(conString, function (err, client, done) {
    if (err) {
      // 将错误传递给 express 错误处理器
      return next(err)
    }
    client.query("INSERT INTO users (name, age) VALUES ($1, $2);", [user.name, user.age], function (err, result) {
      done() //这个 done 回调会通知 pg 驱动程序连接可以被关闭,或者返回给连接缓冲池

      if (err) {
        // 将错误传递给 express 错误处理器
        return next(err)
      }

      res.send(200)
    })
  })
})

完成解锁:用户存储在数据库中!:) 现在我们试着获取他们。下一步,为用户获取给应用程序添加一个新的端点。

app.get("/users", function (req, res, next) {  
  pg.connect(conString, function (err, client, done) {
    if (err) {
      // 将错误传递给 express 错误处理器
      return next(err)
    }
    client.query("SELECT name, age FROM users;", [], function (err, result) {
      done()

      if (err) {
        // 将错误传递给 express 错误处理器
        return next(err)
      }

      res.json(result.rows)
    })
  })
})
也不算很难,对吧?

现在你可以运行提供给 Node.js 应用程序的任何复杂 SQL 查询。

使用这种技术,你可以将数据永久存储在应用程序中,多亏了 Node-postgreSQL 模块团队的辛勤劳动,使存储数据变得易如反掌。

我们已经完成了在 Nodejs 中使用数据库所必须知道的所有基础知识。现在自己去创建一些东西好了。

尝试、实验,因为这是称为一个真正的 Node 勇士的最佳方式。实践并准备下一章如果与第三方 API 通讯!

如果你有任何有本教程相关的或者与在 Node.js 中使用数据库的问题,只管提出来!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84979.html

相关文章

  • Node Hero】1. 开始使用 Node.js

    摘要:使用一个事件驱动的非阻塞式的模型,让它轻量而高效。也就是说提供了用编写服务器的可能性,这种服务器具有令人难以置信的性能。正如官方声明所说是一个使用与浏览器相同引擎的运行时。这意味着有两个发布版本稳定版和试验版。 本文转载自:众成翻译译者:网络埋伏纪事链接:http://www.zcfy.cc/article/1748原文:https://blog.risingstack.com/nod...

    hqman 评论0 收藏0
  • Node Hero】8. 使用 Passport.js 进行 Node.js 身份验证

    摘要:本文转载自众成翻译译者网络埋伏纪事链接原文本教程中将学习如何使用和实现一个本地身份验证策略。我们将有一个用户页,一个备注页,和一些与身份验证相关的功能。下一步下一章主要涉及应用程序的单元测试。你会学习单元测试测试金字塔测试替代等概念。 本文转载自:众成翻译译者:网络埋伏纪事链接:http://www.zcfy.cc/article/1755原文:https://blog.risings...

    CoderStudy 评论0 收藏0
  • Node Hero】7. Node.js 项目结构

    摘要:本教程会学习如何正确组织一个项目的结构,从而在应用程序开始增长时避免混乱。项目结构的五个基本规则组织项目有不少可能的方式并且每种已知的方式都有其兴衰。过去在,我们有机会创建各种规模的高效应用程序,也获得了大量关于项目结构注意事项的见解。 本文转载自:众成翻译译者:网络埋伏纪事链接:http://www.zcfy.cc/article/1756原文:https://blog.rising...

    张红新 评论0 收藏0
  • Node Hero】6. Node.js Request 模块

    摘要:状态码描述了请求的结果,它对错误处理是必不可少的。响应还没完成成功这些状态码表示请求被接收并正确处理了。服务器错误当服务器由于某些错误不能完成有效的请求时,就发送这些状态码。 本文转载自:众成翻译译者:网络埋伏纪事链接:http://www.zcfy.cc/article/1758原文:https://blog.risingstack.com/node-hero-node-js-req...

    BlackHole1 评论0 收藏0
  • Node Hero】9. Node.js 单元测试

    摘要:基本上,测试金字塔描述你应该编写单元测试集成测试和端到端测试。集成测试要比端到端测试多,单元测试甚至要更多一些。应用程序单元测试编写单元测试,是为了看看给定的模块单元是否工作。 本文转载自:众成翻译译者:网络埋伏纪事链接:http://www.zcfy.cc/article/1754原文:https://blog.risingstack.com/node-hero-node-js-un...

    104828720 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<