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

news/2023/12/1 10:42:14

本文转载自:众成翻译
译者:网络埋伏纪事
链接: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,就用你用的包管理器安装它。

Node.js Database Example PostgreSQL

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

如果你打算用一种数据库浏览工具,我推荐使用命令行程序 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 中使用数据库的问题,只管提出来!

图片描述


http://www.niftyadmin.cn/n/685917.html

相关文章

php 安装 apache_apache怎么安装

1.apache官网下载Apache HTTP Server服务器我相信有些朋友刚用apache服务器时,都希望从官网上下载,而面对着官网上众多的项目和镜像以及目录,也许有点茫然。下面是具体步骤:①、打开apache官网http://httpd.apache.org/ (或百度&q…

spring事务处理

JDBC事务 1.获取连接 Connection conDriverManager.getConnection(); 2.开启事务 con.setAutoCommit(true/fase); 3.执行CRUD 4.提交事务或回滚事务 con.commit()/con.rollback() 5.关闭连接 con.close();数据库隔离级别 隔离级别 隔离级别的值 导致的问题 Re…

php命名空间高级应用,来看看,PHP 对象的高级应用怎样实现

1、final 关键字被 final 关键字修饰过的类和方法就是“就是最终版本”。如果一个类的格式为:final class name{……}说明该类不可以继承,也不能有子类。如果一个方法的格式为:final function method name()说明该方法在子类中不可以进行重写…

php统计邮件打开率,如何统计邮件打开率,提高打开率四步走

原标题:如何统计邮件打开率,提高打开率四步走本来只打算教一下大家如何提高邮件打开率,结果发现许多人咨询如何统计邮件打开率。这里就简单说一下。1.统计邮件打开率如果要统计邮件打开率,需要在邮件上加一个透明的小图片&#xf…

mysql grant priv_mysql怎么将grant priv的权限

推荐答案grant 权限 on 数据库对象 to 用户一、grant 普通数据用户,查询、插入、更新、删除 数据库中所有表数据的权利。grant select on testdb.* to common_user’%’grant insert on testdb.* to common_user’%’grant update on testdb.* to common_user’%’g…

easyui-combobox的取值问题

Html代码 例子&#xff1a;<select id"cc" class"easyui-combobox" name"cc" style"width:200px;">在对其取值的时候 Js代码 //不能使用 $(#cc).val() //正确应该 //取ID $(#cc).combobox(getValue) //取显示的name …

通过yml文件获取mysql链接_springcloud通过yml配置文件配置Mysql等相关配置

server:port: 8001mybatis:config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径type-aliases-package: com.atguigu.springcloud.entities # 所有Entity别名类所在包mapper-locations:- classpath:mybatis/mapper/**/*.xml # mapper映射文件spring:…

入门Webpack,看这篇就够了

写在前面的话 阅读本文之前&#xff0c;先看下面这个webpack的配置文件&#xff0c;如果每一项你都懂&#xff0c;那本文能带给你的收获也许就比较有限&#xff0c;你可以快速浏览或直接跳过&#xff1b;如果你和十天前的我一样&#xff0c;对很多选项存在着疑惑&#xff0c;那…

php5.0 64位下载,thinkphp5.0完整版thinkphp5.0完整版 下载 - 51下载网

Tags&#xff1a;51下载网提供《thinkphp5.0完整版》thinkphp5.0完整版 下载&#xff0c;该软件为免费软件&#xff0c;文件大小为3.46 MB&#xff0c;推荐指数4颗星&#xff0c;作为国产软件中的顶尖厂商&#xff0c;完全可以放心下载哦&#xff01;ThinkPHP5.0版本是一个颠覆…

服务端xml文件加解密工具_java加解密文件公用方法整合(多看一本书,少写三行代码)...

最近接到任务(文件的安全性)需要在文件上传到服务器上时将文件加密保存&#xff0c; 用户下载时将文件解密后返回给用户。翻了下方法最后决定用java中的Cipher类来完成(里面的实现方式挺全的)。上手实现。pom.xml文件引入依赖包org.bouncycastlebcprov-jdk15on1.56commons-code…

中国人工智能学会通讯——人工智能落地产业,让我们的生活更美好 2. 创业重要的是企业家精神...

2. 创业重要的是企业家精神 亿欧做什么&#xff1f;亿欧并不是像今天搜狐大数据和支总他们云迹机器人具体做产业内的公司&#xff0c;我们是一家连接科技与产业的服务公司&#xff0c;为大家提供信息平台、提供行业的研究咨询、提供企业落地服务的服务公司&#xff0c;所以我们…

菜鸟教程php 文件上传,php入门学习知识点三 PHP上传

if(is_uploaded_file($_FILES["Imgs"]["tmp_name"])){$phpupfile$_FILES["Imgs"];//输出上传文件的数组结构&#xff1b;print_r($phpupfile);//输出上传文件的各类信息echo $phpupfile["size"].""; //文件名echo $phpupfil…

spring 无法获取父类属性_Spring中存在的设计模式

直接捞干的简单工厂又叫做静态工厂方法(StaticFactory Method)模式&#xff0c;但不属于23种GOF设计模式之一。 简单工厂模式的实质是由一个工厂类根据传入的参数&#xff0c;动态决定应该创建哪一个产品类。 spring中的BeanFactory就是简单工厂模式的体现&#xff0c;根据传入…

数据仓库需要的不是退出历史舞台

文章讲的是数据仓库需要的不是退出历史舞台&#xff0c;国内最受关注的数据库技术盛会——2017第八届中国数据库技术大会(DTCC2017)于2017年5月11-13日如约而至。本届大会以“数据驱动?价值发现”为主题&#xff0c;汇集来自互联网、电子商务、金融、电信、政府、行业协会等20…

mysql gps数据查询_mysql – 获取每个truckId的GPS数据(lat,lon,地址)和最新的时间日期...

一种解决方案,很快就会给卡车最后说明的位置.另一种解决方案是将两列posDateTime和mainId添加到卡车表中并更改触发器中的逻辑.该解决方案假设您有一个支持触发器的mysql版本.-- drop table if exists last_position_for_truck ;CREATE TABLE if not exists last_position_for_…

mysql web环境,Windows(Server)环境安装Web服务器(Apache,PHP,Mysql)图文教程

Windows下ApachePHPMySQL搭建web服务器的方法&#xff0c;windows Server Install Apache PHP MySQL(图文详解)环境准备&#xff1a;Windows Server 2012mysql-5.7httpd-2.4php-5.6 (记得官网下载时看好版本x64 VC11)Apache(httpd)​ 下载之后新建一个wamp目录然后解压进去​ 然…
最新文章