开始使用 PouchDB - 第 1 部分





5.00/5 (12投票s)
随着越来越多的用户在移动设备上与 Web 应用程序进行交互,软件开发人员允许他们离线工作变得越来越重要;PouchDB 可以提供帮助。
引言
随着越来越多的用户在移动设备上与 Web 应用程序进行交互,允许他们离线工作变得越来越重要。在许多情况下,用户需要在离线状态下工作,例如在飞机上、在无法进行蜂窝通信的偏远地区,或者在 Wi-Fi 不可用的巨轮上。如果您可以将数据存储在 Web 应用程序本地,即使没有连接,用户也可以继续工作。
您可能会倾向于使用本地存储,但这种方法非常不规范,访问速度慢,并且不允许存储大量数据。另一种方法是使用 WebSQL,它基于 SQLLite。然而,该规范已被弃用,最终将从浏览器中淘汰。另一种方法是 IndexedDB
,这是一种非常流行的 JavaScript 数据库,专为 Web 应用程序中的本地存储而设计。然而,IndexedDB
的 API 在不同浏览器之间可能略有差异,并且是基于回调的,而不是使用更现代的基于 Promise 的方法。
现在有了 PouchDB
,它在 IndexedDB
之上提供了一个薄的包装器,使所有调用在不同浏览器之间保持一致,并且是基于 Promise 的。这个系列博客文章的第一部分将教您使用 PouchDB
的基础知识。
什么是 PouchDB?
PouchDB
是一个开源的 JavaScript NoSQL 数据库,旨在在浏览器中离线运行。还有一个 PouchDB
服务器版本可以在联机时使用。这两个数据库通过简单的 API 调用进行同步。您也可以在服务器上使用 CouchDB
来同步您的数据。
NoSQL 数据库是一种存储,其中没有像关系数据库那样的固定表结构。NoSQL 数据库有几种不同的方法来存储数据:列式、文档式、图式和键值对。其中,最常见的是列式和文档式。PouchDB
支持面向文档,其中模型中的数据存储为一系列 JSON 对象,每个文档都分配了一个键值。
PouchDB
中的每个文档都必须包含一个名为 _id
的属性。_id
字段的值在数据库中必须是唯一的。您可以为 _id
字段使用任何您想要的 string
值。在本文中,我将使用一个非常简单的值。然而,对于实际应用程序,您可能需要考虑使用 GUID,因为这样可以确保值在与服务器端数据库同步时是完全唯一的。
您可以使用 post()
或 put()
方法将新文档插入数据库,并传入一个 JSON 对象。插入后,您可以通过查找 _id
字段中的值来非常快速地检索该文档,或者您可以使用视图和创建索引来执行其他搜索。
要修改或删除现有文档,您必须首先找到特定文档,然后将整个文档加载到内存中。使用 JavaScript 对任何您想修改的字段进行更改,然后将整个文档保存回数据库。一个名为 _rev
的字段将被创建/更新为新的唯一值,以帮助跟踪哪个文档版本是最新的。
PouchDB 基础知识
为了说明 PouchDB 的基础知识,请创建一个 HTML 项目,并包含 Bootstrap CSS 框架 (www.getbootstrap.com)、PouchDB (www.pouchdb.com) 和 jQuery (www.jquery.com)。添加一个 HTML 页面并添加两个 <div>
语句。第一个 <div>
语句用于显示消息,另一个显示我们 PouchDB
操作返回的 JSON。您可以添加一些 HTML 按钮来调用本文中介绍的各种函数。
<div id="messageArea" class="alert alert-danger hidden">
<span id="message"></span>
</div>
<div id="jsonArea" class="alert alert-info hidden">
<textArea id="json" cols="100" rows="30"></textArea>
</div>
通用 JavaScript
创建一个名为 PouchDBSamples-common.js 的 JavaScript 文件,并添加一个包含以下代码的闭包。此闭包中的代码将在我们的每个示例中用于显示消息、显示 JSON 以及清除消息和 JSON 显示区域。
let pouchDBSamplesCommon = (function () {
//*************************************
//* Private Functions
//*************************************
function displayMessage(msg) {
$("#messageArea").removeClass("hidden");
$("#message").text(msg);
console.log(msg);
}
function displayJSON(data) {
$("#jsonArea").removeClass("hidden");
$("#json").text(JSON.stringify(data, undefined, 2));
}
function hideMessageAreas() {
$("#messageArea").addClass("hidden");
$("#message").text("");
$("#jsonArea").addClass("hidden");
$("#json").text("");
}
//************************************
//* Public Functions
//************************************
return {
displayMessage: displayMessage,
displayJSON: displayJSON,
hideMessageAreas: hideMessageAreas
}
})();
此闭包中的大多数方法都是不言而喻的,但 displayJSON()
方法可能需要稍作解释。我相信您已经熟悉 JSON.stringify()
,但我为它添加了两个额外的参数。第二个参数未使用,因此只需传递 undefined。如果您将数字作为第三个参数传递,它将在字符串化的 JSON 对象中包含指定数量的空格。这将为我们在网页上显示提供格式良好的 JSON 字符串。
打开/创建数据库
在您创建的 HTML 页面上,添加指向 PouchDB、jQuery 和您刚创建的 JavaScript 文件的链接。
<script src="../Scripts/pouchdb-6.4.3.min.js"></script>
<script src="../Scripts/jquery-3.3.1.min.js"></script>
<script src="../Scripts/pouchDBSamplesCommon.js"></script>
在您刚创建的 script
标签正下方添加一个 <script></script>
标签。在这些 script
标签内,创建一个名为 db
的变量。创建一个名为 openCreateDatabase()
的函数,并在该函数内编写代码来创建一个名为 "handyman
" 的新 PouchDB
数据库实例。使用 PouchDB
类的 on()
方法响应 "created
" 事件。如果 PouchDB
数据库成功打开或创建,则数据库名称将传递给此事件。使用闭包显示数据库已准备就绪的消息。
<script>
let db = null;
function openCreateDatabase() {
db = new PouchDB('handyman');
PouchDB.on('created', function (dbName) {
pouchDBSamplesCommon.displayMessage("Database: '" + dbName + "' opened successfully.");
});
}
</script>
在页面上添加一个 HTML 按钮来调用 openCreateDatabase()
函数。
<button class="btn btn-primary" onclick="openCreateDatabase();">
Open/Create Database
</button>
添加一个文档
现在数据库已打开,请调用数据库对象上的 put()
方法将新的 JSON 对象注入数据库。始终使用 put()
方法而不是 post()
方法,因为 put()
会添加或插入文档并设置修订 ID(_rev
字段)。将客户端数据同步到服务器时需要 _rev
字段。
function addTechnician() {
db.put({
_id: 'psheriff',
firstName: 'Pal',
lastName: 'Sheriss',
docType: 'technician'
}).then(function (response) {
pouchDBSamplesCommon.displayJSON(response);
pouchDBSamplesCommon.displayMessage("Technician added.");
}).catch(function (err) {
pouchDBSamplesCommon.displayMessage(err);
});
}
获取一个文档
一旦文档在数据库中,您就可以通过将 _id
值传递给 get()
方法来提取它。此方法返回找到的完整文档,如果未找到文档则抛出错误。
function getTechnician() {
db.get("psheriff")
.then(function (response) {
pouchDBSamplesCommon.displayJSON(response);
}).catch(function (err) {
pouchDBSamplesCommon.displayMessage(err);
});
}
更新文档
为了更新文档,您需要先使用 get()
方法检索整个文档。检索到文档后,设置您想要修改的所有属性,调用 put()
方法,并传入更改后的文档。确保返回 put()
方法的输出,这样新的 Promise 就可以被捕获,您可以检查 update
操作的成功或失败。
function updateTechnician() {
db.get("psheriff")
.then(function (doc) {
// Change the document
doc.firstName = "Paul";
doc.lastName = "Sheriff";
// Update the document
return db.put(doc);
}).then(function (response) {
pouchDBSamplesCommon.displayJSON(response);
pouchDBSamplesCommon.displayMessage("Technician updated.");
}).catch(function (err) {
pouchDBSamplesCommon.displayMessage(err);
});
}
删除文档
在删除文档之前,您需要检索它。将您希望定位的 _id
值传递给 delete
。在 then()
函数中,调用 PouchDB
对象上的 remove()
方法。将完整文档传递给 remove()
方法。或者,您可以将 _id
和 _rev
字段的值传递给 remove()
方法。返回 remove()
方法的输出,它是一个 Promise。这样,您就可以检查 remove
操作的成功或失败。
function deleteTechnician() {
// Get technician
db.get("psheriff")
.then(function (doc) {
// Delete the technician
return db.remove(doc);
}).then(function (response) {
pouchDBSamplesCommon.displayJSON(response);
pouchDBSamplesCommon.displayMessage("Technician deleted.");
}).catch(function (err) {
pouchDBSamplesCommon.displayMessage(err);
});
}
压缩数据库
当您修改文档时,每次都会存储文档的新修订版本。这意味着随着时间的推移,您将拥有同一文档的许多旧版本。并非所有这些都必需,尤其是在您将数据同步到服务器之后。定期调用 compact()
方法以删除旧数据,以使数据库大小保持合理。
function compactDB() {
if (db) {
db.compact().then(function (response) {
pouchDBSamplesCommon.displayJSON(response);
pouchDBSamplesCommon.displayMessage("Database compacted");
}).catch(function (err) {
pouchDBSamplesCommon.displayMessage(err);
});
}
else {
pouchDBSamplesCommon.displayMessage("Please open the database first.");
}
}
删除数据库
如果您不再使用数据库,您可以使用 destroy()
方法将其完全删除。此选项会删除与该数据库相关的所有数据、视图和其他元数据。此操作无法恢复,因此请谨慎操作!
function destroyDatabase() {
if (db) {
db.destroy().then(function (response) {
pouchDBSamplesCommon.displayJSON(response);
pouchDBSamplesCommon.displayMessage("Database deleted.");
}).catch(function (err) {
pouchDBSamplesCommon.displayMessage(err);
});
}
else {
pouchDBSamplesCommon.displayMessage("Please open the database first.");
}
}
摘要
在这篇博客文章中,您了解了 PouchDB
。您学会了如何创建、更新、删除和读取数据库中的文档。您还了解了如何压缩和删除数据库。在接下来的几期博客文章中,您将学习如何批量插入和读取文档、过滤和计数文档、使用 Mango 查询以及使用 map 和 reduce 函数。有关 PouchDB
的更多信息,请访问我位于 https://blog.fairwaytech.com 的博客。