如果要開發(fā)Web應(yīng)用程序,幾乎可以肯定的是,您將不斷與數(shù)據(jù)庫進行交互。在本文中,我們將詳細介紹5種使用JavaScript與數(shù)據(jù)庫進行交互的方法,我們將討論每種方法的優(yōu)缺點。我們將從最低級別的選擇(SQL命令)開始,然后過渡到更高級別的抽象。為JavaScript應(yīng)用程序選擇正確的數(shù)據(jù)庫庫會對代碼的可維護性,可伸縮性和性能產(chǎn)生重大影響,因此值得花一些時間來確定您的選擇。
我們的樣品申請
我們將使用在Heroku上托管的簡單Express應(yīng)用程序作為示例。
先決條件
要運行示例應(yīng)用程序,您的計算機上需要以下軟件:
· 類似于unix的終端環(huán)境(Mac OSX和Linux很好。如果使用Windows,則需要Windows子系統(tǒng)用于Linux)。
· git(和github帳戶)。
· npm(版本6或更高版本)。
· Heroku 命令行工具。
如果您還沒有Heroku帳戶,則需要注冊一個免費帳戶。如果您不想注冊Heroku,也可以針對本地Postgres實例在本地運行該應(yīng)用程序。如果您對此感到滿意,那么應(yīng)該很容易地看到需要進行哪些更改,而不是將它們部署到Heroku。
安裝完以上所有內(nèi)容后,運行heroku login在終端中,您就可以開始了。
生成和部署Hello World應(yīng)用程序,首先,我們將設(shè)置以下內(nèi)容:
· 一個簡單的Express應(yīng)用程序,僅提供“ Hello,World”網(wǎng)頁。
· 一個Postgres的數(shù)據(jù)庫。
· 兩個表,分別代表“用戶”和“評論”(一個用戶有很多評論)。
· 一些樣本數(shù)據(jù)(在這種情況下,是通過mockaroo.com生成的)。
我已經(jīng)創(chuàng)建了一個示例應(yīng)用程序,它將為您進行所有設(shè)置(前提是您已運行)heroku login正如剛才提到的。
這將需要幾分鐘才能完成。在等待時,您可以查看makefile以查看相關(guān)命令,這些命令將執(zhí)行以下操作:
· 創(chuàng)建一個新的Heroku應(yīng)用程序。
· 添加一個Postgres數(shù)據(jù)庫實例。
· 將應(yīng)用程序部署到Heroku。在Heroku上運行命令以設(shè)置數(shù)據(jù)庫表并導(dǎo)入CSV示例數(shù)據(jù)。
· 在新的瀏覽器窗口中打開Heroku應(yīng)用程序的URL。
在此過程結(jié)束時,您應(yīng)該在網(wǎng)頁上看到“ Hello,World”。
使用SQL提取數(shù)據(jù)
我們都準備好了,我們創(chuàng)建了一個包含兩個表和一些示例數(shù)據(jù)的數(shù)據(jù)庫。但是我們還沒有做任何事情。下一步是使我們的Web應(yīng)用程序能夠從數(shù)據(jù)庫檢索數(shù)據(jù)。
每當與關(guān)系數(shù)據(jù)庫進行交互時,都可以通過將SQL命令發(fā)送到數(shù)據(jù)庫正在偵聽的網(wǎng)絡(luò)套接字來實現(xiàn)。對于我們將在本文中介紹的所有庫,都是如此-在最低級別上,它們都將SQL命令發(fā)送到數(shù)據(jù)庫并檢索返回的所有輸出。
因此,我們要考慮的與數(shù)據(jù)庫交互的第一種方法就是執(zhí)行此操作-發(fā)送SQL命令。為此,我們將安裝pg JavaScript庫,該庫使我們可以將SQL發(fā)送到Postgres數(shù)據(jù)庫并檢索結(jié)果。
要安裝pg庫,請執(zhí)行以下命令:
npm install pg
這將獲取并安裝該庫,并將其添加到package.json和package-lock.json文件中。讓我們提交這些更改:
git add package.json package-lock.json gitcommit -m "Install the pg library"
要與我們的數(shù)據(jù)庫對話,我們需要一些細節(jié):
· Postgres機器的主機名正在運行。
· 網(wǎng)絡(luò)端口Postgres正在監(jiān)聽。
· 我們的數(shù)據(jù)所在的數(shù)據(jù)庫的名稱。
· 有權(quán)訪問該數(shù)據(jù)的用戶名和密碼。
大多數(shù)數(shù)據(jù)庫庫將使我們建立連接,方法是向該庫提供一個包含所有這些詳細信息的鍵和值的對象,或者將它們?nèi)拷M合成一個“數(shù)據(jù)庫URL”,這就是我們要做的。
將數(shù)據(jù)庫添加到Heroku應(yīng)用程序時,會自動獲得一個名為DATABASE_URL的環(huán)境變量,其中包含連接數(shù)據(jù)庫所需的所有詳細信息。您可以通過運行以下命令查看DATABASE_URL的值:
heroku config
這將輸出您的應(yīng)用程序可以使用的所有環(huán)境變量。現(xiàn)在應(yīng)該只有一個,因此您應(yīng)該在輸出中看到類似以下的內(nèi)容:
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值將有所不同,但結(jié)構(gòu)將相同。
現(xiàn)在我們已經(jīng)安裝了pg庫,并且知道如何連接到數(shù)據(jù)庫,讓我們執(zhí)行第一個與數(shù)據(jù)庫交互的示例。我們僅獲取用戶列表并將其顯示在我們的網(wǎng)頁上。在index.js文件的頂部,我們將需要pg庫,并創(chuàng)建一個數(shù)據(jù)庫連接對象。
const { Pool } = require('pg');const conn = new Pool({ connectionString: process.env.DATABASE_URL });
在里面express()塊,我們將更改get行以調(diào)用一種方法,該方法顯示數(shù)據(jù)庫中的用戶列表:
.get('/', (req, res) => listUsers(req, res))
最后,我們將實現(xiàn)listUsers函數(shù):
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);
}
}
這段代碼會一直等到與我們的數(shù)據(jù)庫建立連接,然后使用查詢功能發(fā)送SQL查詢并檢索結(jié)果。
現(xiàn)在,由于許多不同的原因,此步驟可能會失敗,因此在代碼中我們進行測試以確保獲得一些數(shù)據(jù),如果這樣做,我們將result.rows分配給結(jié)果對象的關(guān)鍵用戶。接下來,我們將結(jié)果傳遞給render函數(shù),然后釋放數(shù)據(jù)庫連接。
在views / pages / index.ejs中,我們可以訪問結(jié)果對象,因此我們可以這樣顯示用戶數(shù)據(jù):
<h1>Users</h1>
<ul>
<% users.map((user) => { %>
<li><%= user.id %> - <%= user.first_name %> <%= user.last_name %></li>
<% }); %>
</ul>
您可以在此處查看具有這些更改的代碼first_name和last_name是我們數(shù)據(jù)庫的用戶表中兩列的名稱。
讓我們部署這些更改,以便可以在Heroku應(yīng)用程序中查看數(shù)據(jù):
git add index.js views/pages/index.ejs
git commit -m "Display a list of users"
git push heroku master
部署將需要一兩分鐘。該命令執(zhí)行完畢后,重新加載瀏覽器,您應(yīng)該在網(wǎng)頁上看到用戶列表。
MySQL示例
上面的示例適用于Postgres,但是其他常見關(guān)系數(shù)據(jù)庫的代碼將相似。例如,如果您使用的是MySQL:
· 代替npm install pg用npm install mysql2 (使用mysql2,而不是mysql-mysql2更快,并且支持async / await)
· 在index.js中,您將需要這樣的mysql:
const mysql = require('mysql2/promise');
· listUsers函數(shù)如下所示:
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保持不變。您可以在此處查看帶有這些更改的示例項目。
我們在這里已經(jīng)介紹了很多基礎(chǔ)知識,但這對于理解所有數(shù)據(jù)庫訪問的工作方式都是至關(guān)重要的。在下一部分中,我們將看到查詢構(gòu)建器和對象關(guān)系建模庫如何在此基礎(chǔ)上構(gòu)建,從而使您可以以一種更像使用JavaScript函數(shù)和對象的方式來使用代碼中的數(shù)據(jù)庫數(shù)據(jù)。想了解更多關(guān)于數(shù)據(jù)庫的信息,請繼續(xù)關(guān)注中培偉業(yè)。