如果要开发Web应用程序,几乎可以肯定的是,您将不断与数据库进行交互。在本文中,我们将详细介绍5种使用JavaScript与数据库进行交互的方法,我们将讨论每种方法的优缺点。我们将从最低级别的选择(SQL命令)开始,然后过渡到更高级别的抽象。为JavaScript应用程序选择正确的数据库库会对代码的可维护性,可伸缩性和性能产生重大影响,因此值得花一些时间来确定您的选择。
我们的样品申请
我们将使用在Heroku上托管的简单Express应用程序作为示例。
先决条件
要运行示例应用程序,您的计算机上需要以下软件:
· 类似于unix的终端环境(Mac OSX和Linux很好。如果使用Windows,则需要Windows子系统用于Linux)。
· git(和github帐户)。
· npm(版本6或更高版本)。
· Heroku 命令行工具。
如果您还没有Heroku帐户,则需要注册一个免费帐户。如果您不想注册Heroku,也可以针对本地Postgres实例在本地运行该应用程序。如果您对此感到满意,那么应该很容易地看到需要进行哪些更改,而不是将它们部署到Heroku。
安装完以上所有内容后,运行heroku login在终端中,您就可以开始了。
生成和部署Hello World应用程序,首先,我们将设置以下内容:
· 一个简单的Express应用程序,仅提供“ Hello,World”网页。
· 一个Postgres的数据库。
· 两个表,分别代表“用户”和“评论”(一个用户有很多评论)。
· 一些样本数据(在这种情况下,是通过mockaroo.com生成的)。
我已经创建了一个示例应用程序,它将为您进行所有设置(前提是您已运行)heroku login正如刚才提到的。
这将需要几分钟才能完成。在等待时,您可以查看makefile以查看相关命令,这些命令将执行以下操作:
· 创建一个新的Heroku应用程序。
· 添加一个Postgres数据库实例。
· 将应用程序部署到Heroku。在Heroku上运行命令以设置数据库表并导入CSV示例数据。
· 在新的浏览器窗口中打开Heroku应用程序的URL。
在此过程结束时,您应该在网页上看到“ Hello,World”。
使用SQL提取数据
我们都准备好了,我们创建了一个包含两个表和一些示例数据的数据库。但是我们还没有做任何事情。下一步是使我们的Web应用程序能够从数据库检索数据。
每当与关系数据库进行交互时,都可以通过将SQL命令发送到数据库正在侦听的网络套接字来实现。对于我们将在本文中介绍的所有库,都是如此-在最低级别上,它们都将SQL命令发送到数据库并检索返回的所有输出。
因此,我们要考虑的与数据库交互的第一种方法就是执行此操作-发送SQL命令。为此,我们将安装pg JavaScript库,该库使我们可以将SQL发送到Postgres数据库并检索结果。
要安装pg库,请执行以下命令:
npm install pg
这将获取并安装该库,并将其添加到package.json和package-lock.json文件中。让我们提交这些更改:
git add package.json package-lock.json gitcommit -m "Install the pg library"
要与我们的数据库对话,我们需要一些细节:
· Postgres机器的主机名正在运行。
· 网络端口Postgres正在监听。
· 我们的数据所在的数据库的名称。
· 有权访问该数据的用户名和密码。
大多数数据库库将使我们建立连接,方法是向该库提供一个包含所有这些详细信息的键和值的对象,或者将它们全部组合成一个“数据库URL”,这就是我们要做的。
将数据库添加到Heroku应用程序时,会自动获得一个名为DATABASE_URL的环境变量,其中包含连接数据库所需的所有详细信息。您可以通过运行以下命令查看DATABASE_URL的值:
heroku config
这将输出您的应用程序可以使用的所有环境变量。现在应该只有一个,因此您应该在输出中看到类似以下的内容:
DATABASE_URL:
postgres://clqcouauvejtvw:1b079cad50f3ff9b48948f15a7fa52123bc6795b875348d66886407a266c0f5b@ec2-52-73-247-67.compute-1.amazonaws.com:5432/dfb3aad8c026in
在我们的示例中,这种情况如下所示:
{
"hostname": "ec2-52-73-247-67.compute-1.amazonaws.com",
"port": 5432,
"database": "dfb3aad8c026in",
"username": "clqcouauvejtvw",
"password": "1b079cad50f3ff9b48948f15a7fa52123bc6795b875348d66886407a266c0f5b"
}
您的DATABASE_URL值将有所不同,但结构将相同。
现在我们已经安装了pg库,并且知道如何连接到数据库,让我们执行第一个与数据库交互的示例。我们仅获取用户列表并将其显示在我们的网页上。在index.js文件的顶部,我们将需要pg库,并创建一个数据库连接对象。
const { Pool } = require('pg');const conn = new Pool({ connectionString: process.env.DATABASE_URL });
在里面express()块,我们将更改get行以调用一种方法,该方法显示数据库中的用户列表:
.get('/', (req, res) => listUsers(req, res))
最后,我们将实现listUsers函数:
async function listUsers(req, res) {
try {
const db = await conn.connect()
const result = await db.query('SELECT * FROM users');
const results = { users: (result) ? result.rows : null};
res.render('pages/index', results );
db.release();
} catch (err) {
console.error(err);
res.send("Error " + err);
}
}
这段代码会一直等到与我们的数据库建立连接,然后使用查询功能发送SQL查询并检索结果。
现在,由于许多不同的原因,此步骤可能会失败,因此在代码中我们进行测试以确保获得一些数据,如果这样做,我们将result.rows分配给结果对象的关键用户。接下来,我们将结果传递给render函数,然后释放数据库连接。
在views / pages / index.ejs中,我们可以访问结果对象,因此我们可以这样显示用户数据:
<h1>Users</h1>
<ul>
<% users.map((user) => { %>
<li><%= user.id %> - <%= user.first_name %> <%= user.last_name %></li>
<% }); %>
</ul>
您可以在此处查看具有这些更改的代码first_name和last_name是我们数据库的用户表中两列的名称。
让我们部署这些更改,以便可以在Heroku应用程序中查看数据:
git add index.js views/pages/index.ejs
git commit -m "Display a list of users"
git push heroku master
部署将需要一两分钟。该命令执行完毕后,重新加载浏览器,您应该在网页上看到用户列表。
MySQL示例
上面的示例适用于Postgres,但是其他常见关系数据库的代码将相似。例如,如果您使用的是MySQL:
· 代替npm install pg用npm install mysql2 (使用mysql2,而不是mysql-mysql2更快,并且支持async / await)
· 在index.js中,您将需要这样的mysql:
const mysql = require('mysql2/promise');
· listUsers函数如下所示:
async function listUsers(req, res) {
try {
const conn = await mysql.createConnection(process.env.DATABASE_URL);
const [rows, fields] = await conn.execute('SELECT * FROM users');
const results = { 'users': rows };
res.render('pages/index', results );
await conn.end();
} catch (err) {
console.error(err);
res.send("Error " + err);
}
}
views / pages / index.ejs保持不变。您可以在此处查看带有这些更改的示例项目。
我们在这里已经介绍了很多基础知识,但这对于理解所有数据库访问的工作方式都是至关重要的。在下一部分中,我们将看到查询构建器和对象关系建模库如何在此基础上构建,从而使您可以以一种更像使用JavaScript函数和对象的方式来使用代码中的数据库数据。想了解更多关于数据库的信息,请继续关注。