In diesem Leitfaden werden die Grundlagen der
IndexedDB API.
Mit dem von Jake Archibald
IndexedDB versprochen
die dem IndexedDB API sehr ähnlich ist, aber Promise verwendet,
Sie können await
für eine kürzere Syntax. Dies vereinfacht die API und
und die Struktur beibehalten.
Was ist IndexedDB?
IndexedDB ist ein umfangreiches NoSQL-Speichersystem, mit dem nur über alles im Browser der Nutzenden. Zusätzlich zu den üblichen Such-, Abruf- und put-Aktionen unterstützt, unterstützt IndexedDB auch Transaktionen und eignet sich gut für große Mengen strukturierter Daten speichern.
Jede IndexedDB-Datenbank ist für einen Ursprung eindeutig. (normalerweise die Websitedomain oder Subdomain), d. h., der Zugriff ist nicht möglich. irgendetwas anderem Ursprung. Die Limits für die Datenspeicherung normalerweise groß sind, wenn sie überhaupt vorhanden sind, aber unterschiedliche Browser und die Datenbereinigung unterscheiden. Im Abschnitt Weitere Informationen finden Sie erhalten Sie weitere Informationen.
IndexedDB-Begriffe
- Datenbank
- Die höchste Indexebene. Es enthält die Objektspeicher, die wiederum die Daten enthalten, die Sie dauerhaft speichern möchten. Sie können mehrere Datenbanken mit welchen Namen ihr wählt.
- Objektspeicher
- Ein einzelner Bucket zum Speichern von Daten, ähnlich wie Tabellen in relationalen Datenbanken.
In der Regel gibt es einen Objektspeicher für jeden Typ (keine JavaScript-Daten).
Typ) der Daten, die Sie speichern. Im Gegensatz zu Datenbanktabellen werden die JavaScript-Daten
Datentypen in einem Speicher nicht
einheitlich sein müssen. Wenn beispielsweise eine App
einen
people
-Objektspeicher mit Informationen über drei Personen hat, können die Alters-Properties der Nutzer53
,'twenty-five'
undunknown
sein. - Index
- Eine Art von Objektspeicher zum Organisieren von Daten in einem anderen Objektspeicher Referenzobjektspeicher) durch eine einzelne Eigenschaft der Daten. Der Index wird verwendet, , um Datensätze im Objektspeicher nach dieser Eigenschaft abzurufen. Wenn Sie zum Beispiel oder Personen speichern, möchten Sie diese später vielleicht anhand ihres Namens, ihres Alters oder Lieblingstier.
- Vorgang
- Eine Interaktion mit der Datenbank.
- Transaktion
- Ein Wrapper um einen Vorgang oder eine Gruppe von Vorgängen, der die Datenbank stellt Integrität. Wenn eine der Aktionen in einer Transaktion fehlschlägt, wird keine der Aktionen ausgeführt. angewendet und die Datenbank kehrt in den Status zurück, in dem sie sich vor der Transaktion befand. begonnen. Alle Lese- oder Schreibvorgänge in IndexedDB müssen Teil einer Transaktion sein. Dies ermöglicht atomare Read-Change-Write-Vorgänge ohne Konfliktrisiko. und andere Threads, die gleichzeitig auf die Datenbank reagieren.
- Cursor
- Ein Mechanismus zum Iterieren über mehrere Datensätze in einer Datenbank.
IndexedDB-Unterstützung prüfen
IndexedDB wird fast allgemein unterstützt.
Bei älteren Browsern ist es jedoch keine gute Idee,
Funktionserkennung unterstützen. Am einfachsten ist es, wenn du dir die window
ansiehst
-Objekt enthält:
function indexedDBStuff () {
// Check for IndexedDB support:
if (!('indexedDB' in window)) {
// Can't use IndexedDB
console.log("This browser doesn't support IndexedDB");
return;
} else {
// Do IndexedDB stuff here:
// ...
}
}
// Run IndexedDB code:
indexedDBStuff();
Datenbank öffnen
Mit IndexedDB können Sie mehrere Datenbanken mit beliebigen Namen erstellen. Wenn
wenn man versucht, eine Datenbank zu öffnen, automatisch erstellt wird.
Verwenden Sie zum Öffnen einer Datenbank die Methode openDB()
aus der idb
-Bibliothek:
import {openDB} from 'idb';
async function useDB () {
// Returns a promise, which makes `idb` usable with async-await.
const dbPromise = await openDB('example-database', version, events);
}
useDB();
Diese Methode gibt ein Promise zurück, das in ein Datenbankobjekt aufgelöst wird. Bei Verwendung des
openDB()
-Methode einen Namen, eine Versionsnummer und ein festzulegendes Ereignisobjekt an
in der Datenbank arbeiten.
Hier ein Beispiel für die Methode openDB()
im Kontext:
import {openDB} from 'idb';
async function useDB () {
// Opens the first version of the 'test-db1' database.
// If the database does not exist, it will be created.
const dbPromise = await openDB('test-db1', 1);
}
useDB();
Setzen Sie die Prüfung auf IndexedDB-Unterstützung oben in der anonymen Funktion. Dieses
beendet die Funktion, wenn der Browser IndexedDB nicht unterstützt. Wenn die Funktion
wird die Methode openDB()
aufgerufen, um eine Datenbank namens 'test-db1'
zu öffnen.
In diesem Beispiel wurde das optionale Ereignisobjekt weggelassen, damit
einfach, aber Sie müssen sie angeben, um sinnvolle Arbeit mit IndexedDB auszuführen.
Mit Objektspeichern arbeiten
Eine IndexedDB-Datenbank enthält einen oder mehrere Objektspeicher, die jeweils über einen für einen Schlüssel und eine weitere Spalte für die mit diesem Schlüssel verknüpften Daten.
Objektspeicher erstellen
Eine gut strukturierte IndexedDB-Datenbank sollte einen Objektspeicher für jeden Typ haben
die beibehalten werden müssen. Beispiel: Eine Website, die Nutzer*innen
Profile und Notizen haben möglicherweise einen people
-Objektspeicher, der person
enthält.
-Objekte und einen notes
-Objektspeicher mit note
-Objekten.
Um die Datenbankintegrität zu gewährleisten, können Sie Objektspeicher nur in der
Event-Objekt in einem openDB()
-Aufruf an. Das Ereignisobjekt stellt ein upgrade()
-Objekt bereit.
Methode, mit der Sie Objektspeicher erstellen können. Rufen Sie die Methode
createObjectStore()
innerhalb der Methode upgrade()
zum Erstellen des Objektspeichers:
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('example-database', 1, {
upgrade (db) {
// Creates an object store:
db.createObjectStore('storeName', options);
}
});
}
createStoreInDB();
Diese Methode verwendet den Namen des Objektspeichers und eine optionale Konfiguration -Objekt, mit dem Sie verschiedene Eigenschaften für den Objektspeicher definieren können.
Hier ein Beispiel für die Verwendung von createObjectStore()
:
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('test-db1', 1, {
upgrade (db) {
console.log('Creating a new object store...');
// Checks if the object store exists:
if (!db.objectStoreNames.contains('people')) {
// If the object store does not exist, create it:
db.createObjectStore('people');
}
}
});
}
createStoreInDB();
In diesem Beispiel wird ein Ereignisobjekt an die Methode openDB()
übergeben, um ein
Objektspeicher. Wie zuvor ist die Erstellung des Objektspeichers abgeschlossen.
in der Methode upgrade()
des Ereignisobjekts. Da der Browser jedoch eine Fehlermeldung
wenn Sie versuchen, einen bereits vorhandenen Objektspeicher zu erstellen,
createObjectStore()
-Methode in eine if
-Anweisung verpacken, die
Gibt an, ob der Objektspeicher vorhanden ist. Rufen Sie im if
-Block Folgendes auf:
createObjectStore()
, um einen Objektspeicher mit dem Namen 'firstOS'
zu erstellen.
So definieren Sie Primärschlüssel
Beim Definieren von Objektspeichern können Sie festlegen, wie Daten in mit einem Primärschlüssel. Sie können einen Primärschlüssel definieren, indem Sie entweder einen oder mit einem Schlüsselgenerator.
Ein Schlüsselpfad ist ein Attribut, das immer vorhanden ist und einen eindeutigen Wert enthält. Für
Bei einem people
-Objektspeicher können Sie z. B. die E-Mail-Adresse
address als Schlüsselpfad:
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('test-db2', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('people')) {
db.createObjectStore('people', { keyPath: 'email' });
}
}
});
}
createStoreInDB();
In diesem Beispiel wird ein Objektspeicher mit dem Namen 'people'
erstellt und dem Objekt email
zugewiesen.
bei der Option keyPath
als Primärschlüssel verwenden.
Sie können auch einen Schlüsselgenerator wie autoIncrement
verwenden. Der Schlüsselgenerator
erstellt einen eindeutigen Wert für jedes Objekt, das dem Objektspeicher hinzugefügt wird. Standardmäßig
Wenn Sie keinen Schlüssel angeben, erstellt IndexedDB einen Schlüssel und speichert ihn separat
Daten zu extrahieren.
Im folgenden Beispiel wird ein Objektspeicher namens 'notes'
erstellt und der
Primärschlüssel, der automatisch als automatisch zunehmende Nummer zugewiesen wird:
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('test-db2', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('notes')) {
db.createObjectStore('notes', { autoIncrement: true });
}
}
});
}
createStoreInDB();
Das folgende Beispiel ähnelt dem vorherigen Beispiel, aber diesmal
Der automatisch inkrementierende Wert wird explizit einer Property namens 'id'
zugewiesen.
import {openDB} from 'idb';
async function createStoreInDB () {
const dbPromise = await openDB('test-db2', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('logs')) {
db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
}
}
});
}
createStoreInDB();
Die Auswahl der Methode zum Definieren des Schlüssels hängt von Ihren Daten ab. Wenn Ihr
Daten eine Eigenschaft haben, die immer eindeutig ist, können Sie sie zur keyPath
machen,
um diese Einzigartigkeit zu erzwingen. Andernfalls verwenden Sie einen Wert mit automatischer Inkrementierung.
Mit dem folgenden Code werden drei Objektspeicher erstellt, die die verschiedenen Möglichkeiten Definition von Primärschlüsseln in Objektspeichern:
import {openDB} from 'idb';
async function createStoresInDB () {
const dbPromise = await openDB('test-db2', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('people')) {
db.createObjectStore('people', { keyPath: 'email' });
}
if (!db.objectStoreNames.contains('notes')) {
db.createObjectStore('notes', { autoIncrement: true });
}
if (!db.objectStoreNames.contains('logs')) {
db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
}
}
});
}
createStoresInDB();
Indexe definieren
Indexe sind eine Art von Objektspeicher, der zum Abrufen von Daten aus der Referenz verwendet wird. Objektspeicher durch eine angegebene Property. Ein Index befindet sich im Referenzobjekt gespeichert ist und dieselben Daten enthält, aber die angegebene Eigenschaft als Schlüsselpfad anstelle des Primärschlüssels des Referenzspeichers. Indizes müssen erstellt werden, wenn erstellen Sie Ihre Objektspeicher und können verwendet werden, um eine eindeutige Ihre Daten.
Rufen Sie zum Erstellen eines Index den createIndex()
auf.
-Methode für eine Objektspeicherinstanz:
import {openDB} from 'idb';
async function createIndexInStore() {
const dbPromise = await openDB('storeName', 1, {
upgrade (db) {
const objectStore = db.createObjectStore('storeName');
objectStore.createIndex('indexName', 'property', options);
}
});
}
createIndexInStore();
Diese Methode erstellt ein Indexobjekt und gibt es zurück. Die Methode createIndex()
für
Für die Instanz des Objektspeichers wird der Name des neuen Index als erste
und das zweite Argument sich auf die Eigenschaft der Daten bezieht,
-Index. Mit dem letzten Argument können Sie zwei Optionen definieren,
der Index wird ausgeführt: unique
und multiEntry
. Wenn unique
auf true
gesetzt ist, gibt der Parameter
lassen keine doppelten Werte für einen einzelnen Schlüssel zu. Als Nächstes: multiEntry
legt fest, wie sich createIndex()
verhält, wenn die indexierte Eigenschaft ein Array ist. Wenn
auf true
festgelegt ist, fügt createIndex()
dem Index für jedes Array einen Eintrag hinzu.
-Elements. Andernfalls wird ein einzelner Eintrag mit dem Array hinzugefügt.
Beispiel:
import {openDB} from 'idb';
async function createIndexesInStores () {
const dbPromise = await openDB('test-db3', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('people')) {
const peopleObjectStore = db.createObjectStore('people', { keyPath: 'email' });
peopleObjectStore.createIndex('gender', 'gender', { unique: false });
peopleObjectStore.createIndex('ssn', 'ssn', { unique: true });
}
if (!db.objectStoreNames.contains('notes')) {
const notesObjectStore = db.createObjectStore('notes', { autoIncrement: true });
notesObjectStore.createIndex('title', 'title', { unique: false });
}
if (!db.objectStoreNames.contains('logs')) {
const logsObjectStore = db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
}
}
});
}
createIndexesInStores();
In diesem Beispiel haben die Objektspeicher 'people'
und 'notes'
Indexe. Bis
Weisen Sie zum Erstellen der Indexe zuerst das Ergebnis von createObjectStore()
(einem Objekt) zu.
Objekt) in eine Variable zu übertragen, damit Sie createIndex()
dafür aufrufen können.
Mit Daten arbeiten
In diesem Abschnitt wird beschrieben, wie Sie Daten erstellen, lesen, aktualisieren und löschen. Diese
Operationen sind alle asynchron und verwenden Promise, wo die IndexedDB API
-Anfragen. Dies vereinfacht die API. Anstatt auf Ereignisse zu warten, die durch
der Anfrage haben, können Sie .then()
für das Datenbankobjekt aufrufen, das vom
openDB()
, um Interaktionen mit der Datenbank zu starten, oder await
ihre
Erstellung.
Alle Datenvorgänge in IndexedDB werden innerhalb einer Transaktion ausgeführt. Jedes hat der Vorgang folgende Form:
- Datenbankobjekt abrufen.
- Transaktion in der Datenbank öffnen.
- Objektspeicher bei Transaktion öffnen.
- Vorgang für Objektspeicher ausführen.
Eine Transaktion kann als ein sicherer Wrapper um einen Vorgang oder eine Gruppe betrachtet werden. der Betriebsabläufe. Wenn eine der Aktionen innerhalb einer Transaktion fehlschlägt, für Aktionen wird ein Rollback durchgeführt. Transaktionen gelten für einen oder mehrere Objektspeicher, den Sie beim Öffnen der Transaktion definieren. Sie können schreibgeschützt sein und schreiben. Dieser Wert gibt an, ob die Operationen innerhalb der Transaktion den oder eine Änderung an der Datenbank vornehmen.
Daten erstellen
Rufen Sie zum Erstellen von Daten den add()
auf.
auf der Datenbankinstanz und übergeben Sie die Daten, die Sie hinzufügen möchten. Das add()
Das erste Argument der Methode ist der Objektspeicher, dem die Daten hinzugefügt werden sollen. Der
Das zweite Argument ist ein Objekt, das die gewünschten Felder und zugehörigen Daten enthält.
hinzuzufügen. Hier ist das einfachste Beispiel, bei dem eine einzelne Datenzeile hinzugefügt wird:
import {openDB} from 'idb';
async function addItemToStore () {
const db = await openDB('example-database', 1);
await db.add('storeName', {
field: 'data'
});
}
addItemToStore();
Jeder add()
-Aufruf findet innerhalb einer Transaktion statt. Selbst wenn das Promise aufgelöst wird,
bedeutet das nicht unbedingt, dass der Vorgang funktioniert hat. Um sicherzustellen,
der Hinzufügung ausgeführt wurde, müssen Sie überprüfen,
Transaktion mit der Methode transaction.done()
abgeschlossen. Dies ist ein
Versprechen, das aufgelöst wird, wenn die Transaktion von selbst abgeschlossen wird, und ablehnt, wenn der
Transaktionsfehler. Diese Prüfung muss für alle Schreibvorgänge durchgeführt werden, Betriebsabläufe
denn nur so erfahren Sie,
welche Änderungen an der Datenbank
passiert ist.
Der folgende Code zeigt die Verwendung der Methode add()
innerhalb einer Transaktion:
import {openDB} from 'idb';
async function addItemsToStore () {
const db = await openDB('test-db4', 1, {
upgrade (db) {
if (!db.objectStoreNames.contains('foods')) {
db.createObjectStore('foods', { keyPath: 'name' });
}
}
});
// Create a transaction on the 'foods' store in read/write mode:
const tx = db.transaction('foods', 'readwrite');
// Add multiple items to the 'foods' store in a single transaction:
await Promise.all([
tx.store.add({
name: 'Sandwich',
price: 4.99,
description: 'A very tasty sandwich!',
created: new Date().getTime(),
}),
tx.store.add({
name: 'Eggs',
price: 2.99,
description: 'Some nice eggs you can cook up!',
created: new Date().getTime(),
}),
tx.done
]);
}
addItemsToStore();
Nachdem Sie die Datenbank geöffnet (und bei Bedarf einen Objektspeicher erstellt haben) müssen Sie
, um eine Transaktion durch Aufrufen der transaction()
-Methode zu öffnen. Diese Methode
ein Argument für den Store, für den Sie eine Transaktion durchführen möchten, sowie den Modus.
In diesem Fall möchten wir an den Store schreiben.
gibt 'readwrite'
an.
Im nächsten Schritt fügen Sie dem Shop Artikel als Teil der Transaktion hinzu.
Im vorherigen Beispiel haben wir drei Vorgänge für die 'foods'
dass jeder ein Versprechen zurückgibt:
- Sie fügen einen Eintrag für ein leckeres Sandwich hinzu.
- Es wird ein Eintrag für ein paar Eier hinzugefügt.
- Signalisiert, dass die Transaktion abgeschlossen ist (
tx.done
).
Da all diese Aktionen versprochen werden, müssen wir warten,
bis zum Ende. Die Übergabe dieser Versprechen an
Promise.all
ist eine praktische und ergonomische Art, dies zu erledigen. Promise.all
akzeptiert ein Array von
und endet, wenn alle Versprechen,
die an sie übergeben wurden, gelöst sind.
Für die beiden hinzuzufügenden Datensätze hat die store
-Schnittstelle der Transaktionsinstanz
add()
aufruft und die Daten an sie übergibt. Sie können den Promise.all
-Anruf await
sodass es nach Abschluss der Transaktion
abgeschlossen wird.
Daten lesen
Rufen Sie zum Lesen von Daten den get()
auf.
auf der Datenbankinstanz, die Sie mit der Methode openDB()
abrufen.
get()
übernimmt den Namen des Speichers und den Primärschlüsselwert des Objekts, das Sie
die Sie abrufen möchten. Hier ein einfaches Beispiel:
import {openDB} from 'idb';
async function getItemFromStore () {
const db = await openDB('example-database', 1);
// Get a value from the object store by its primary key value:
const value = await db.get('storeName', 'unique-primary-key-value');
}
getItemFromStore();
Wie bei add()
gibt die Methode get()
ein Promise zurück, sodass du es await
oder verwende den .then()
-Callback des Versprechens.
Im folgenden Beispiel wird die Methode get()
für die Datenbank 'test-db4'
'foods'
, um eine einzelne Zeile mit dem Primärschlüssel 'name'
abzurufen:
import {openDB} from 'idb';
async function getItemFromStore () {
const db = await openDB('test-db4', 1);
const value = await db.get('foods', 'Sandwich');
console.dir(value);
}
getItemFromStore();
Das Abrufen einer einzelnen Zeile aus der Datenbank ist ziemlich einfach: offen
Datenbank und geben Sie den Objektspeicher und den Primärschlüsselwert der Zeile an,
Daten abrufen möchten. Da die Methode get()
ein Promise zurückgibt, kannst du
await
.
Daten aktualisieren
Rufen Sie zum Aktualisieren von Daten den put()
auf.
im Objektspeicher. Die Methode put()
ähnelt der Methode add()
und kann auch anstelle von add()
verwendet werden, um Daten zu erstellen. Hier ein einfaches Beispiel:
wie Sie put()
verwenden, um eine Zeile in einem Objektspeicher mit ihrem Primärschlüsselwert zu aktualisieren:
import {openDB} from 'idb';
async function updateItemInStore () {
const db = await openDB('example-database', 1);
// Update a value from in an object store with an inline key:
await db.put('storeName', { inlineKeyName: 'newValue' });
// Update a value from in an object store with an out-of-line key.
// In this case, the out-of-line key value is 1, which is the
// auto-incremented value.
await db.put('otherStoreName', { field: 'value' }, 1);
}
updateItemInStore();
Wie andere Methoden gibt diese Methode ein Promise zurück. Sie können put()
auch als
Teil einer Transaktion ist. Hier ein Beispiel für den 'foods'
-Shop
der den Preis für das Sandwich und die Eier aktualisiert:
import {openDB} from 'idb';
async function updateItemsInStore () {
const db = await openDB('test-db4', 1);
// Create a transaction on the 'foods' store in read/write mode:
const tx = db.transaction('foods', 'readwrite');
// Update multiple items in the 'foods' store in a single transaction:
await Promise.all([
tx.store.put({
name: 'Sandwich',
price: 5.99,
description: 'A MORE tasty sandwich!',
updated: new Date().getTime() // This creates a new field
}),
tx.store.put({
name: 'Eggs',
price: 3.99,
description: 'Some even NICER eggs you can cook up!',
updated: new Date().getTime() // This creates a new field
}),
tx.done
]);
}
updateItemsInStore();
Wie Elemente aktualisiert werden, hängt davon ab, wie Sie einen Schlüssel festlegen. Wenn Sie eine keyPath
festlegen,
Jede Zeile im Objektspeicher ist mit einem Inline-Schlüssel verknüpft. Die vorherige
Beispiel Zeilen basierend auf diesem Schlüssel aktualisiert. Wenn Sie Zeilen in diesem
müssen Sie diesen Schlüssel angeben, um das entsprechende Element im
Objektspeicher Sie können auch einen Out-of-Line-Schlüssel erstellen, indem Sie ein
autoIncrement
als Primärschlüssel.
Daten löschen
Rufe zum Löschen von Daten die delete()
auf
im Objektspeicher:
import {openDB} from 'idb';
async function deleteItemFromStore () {
const db = await openDB('example-database', 1);
// Delete a value
await db.delete('storeName', 'primary-key-value');
}
deleteItemFromStore();
Wie add()
und put()
können Sie auch diesen Teil einer Transaktion verwenden:
import {openDB} from 'idb';
async function deleteItemsFromStore () {
const db = await openDB('test-db4', 1);
// Create a transaction on the 'foods' store in read/write mode:
const tx = db.transaction('foods', 'readwrite');
// Delete multiple items from the 'foods' store in a single transaction:
await Promise.all([
tx.store.delete('Sandwich'),
tx.store.delete('Eggs'),
tx.done
]);
}
deleteItemsFromStore();
Die Struktur der Datenbankinteraktion ist dieselbe wie bei der anderen
Geschäftsabläufe. Überprüfen Sie, ob die gesamte Transaktion abgeschlossen ist, indem Sie
einschließlich der Methode tx.done
in das Array, das Sie an Promise.all
übergeben.
Alle Daten werden abgerufen
Bisher haben Sie jeweils nur Objekte aus dem Speicher abgerufen. Sie können auch
alle Daten oder eine Teilmenge aus einem Objektspeicher oder -index mithilfe
getAll()
-Methode oder Cursors ein.
Die Methode getAll()
Die einfachste Möglichkeit, alle Daten eines Objektspeichers abzurufen, ist der Aufruf von getAll()
.
für den Objektspeicher oder -index erstellt:
import {openDB} from 'idb';
async function getAllItemsFromStore () {
const db = await openDB('test-db4', 1);
// Get all values from the designated object store:
const allValues = await db.getAll('storeName');
console.dir(allValues);
}
getAllItemsFromStore();
Diese Methode gibt alle Objekte im Objektspeicher ohne Einschränkungen zurück. überhaupt nicht. Dies ist die direkteste Methode, um alle Werte aus einem Objektspeicher abzurufen. aber auch am wenigsten flexibel ist.
import {openDB} from 'idb';
async function getAllItemsFromStore () {
const db = await openDB('test-db4', 1);
// Get all values from the designated object store:
const allValues = await db.getAll('foods');
console.dir(allValues);
}
getAllItemsFromStore();
In diesem Beispiel wird getAll()
im Objektspeicher 'foods'
aufgerufen. Dadurch werden alle
Die Objekte aus 'foods'
, sortiert nach Primärschlüssel.
Cursor verwenden
Cursor bieten eine flexiblere Möglichkeit, mehrere Objekte abzurufen. Ein Cursor wählt eine in einem Objektspeicher oder Objektindex nach dem anderen in den Index aufnehmen, mit den Daten, wenn diese ausgewählt sind. Cursors, wie die anderen Datenbankvorgänge, Transaktionen.
Rufen Sie openCursor()
auf, um einen Cursor zu erstellen.
im Objektspeicher als Teil einer Transaktion. 'foods'
-Speicher von
vorherigen Beispielen gezeigt, wie ein Cursor durch alle Datenzeilen in
Objektspeicher:
import {openDB} from 'idb';
async function getAllItemsFromStoreWithCursor () {
const db = await openDB('test-db4', 1);
const tx = await db.transaction('foods', 'readonly');
// Open a cursor on the designated object store:
let cursor = await tx.store.openCursor();
// Iterate on the cursor, row by row:
while (cursor) {
// Show the data in the row at the current cursor position:
console.log(cursor.key, cursor.value);
// Advance the cursor to the next row:
cursor = await cursor.continue();
}
}
getAllItemsFromStoreWithCursor();
Die Transaktion wird in diesem Fall im 'readonly'
-Modus geöffnet und
openCursor
-Methode wird aufgerufen. In einer nachfolgenden while
-Schleife wird die Zeile bei
Die aktuelle Position des Cursors kann die Eigenschaften key
und value
lesen und
können Sie diese Werte so verwenden, wie es für Ihr Unternehmen
Wenn Sie bereit sind, können Sie die continue()
des cursor
-Objekts aufrufen.
um zur nächsten Zeile zu gelangen, und die while
-Schleife endet, wenn der Cursor
das Ende des Datasets erreicht.
Cursor mit Bereichen und Indexen verwenden
Mit Indizes können Sie die Daten in einem Objektspeicher anhand einer anderen Eigenschaft als der
Primärschlüssel. Sie können für jedes Attribut einen Index erstellen, das zum keyPath
wird
für den Index, geben Sie einen Bereich für diese Eigenschaft an und rufen Sie die Daten innerhalb der
mithilfe von getAll()
oder einem Cursor.
Definieren Sie den Bereich mit dem Objekt IDBKeyRange
. und einer der folgenden
Methoden:
upperBound()
.lowerBound()
.bound()
(beides ist)only()
.includes()
.
Die Methoden upperBound()
und lowerBound()
geben die oberen und unteren Grenzwerte an
des Bereichs.
IDBKeyRange.lowerBound(indexKey);
Oder:
IDBKeyRange.upperBound(indexKey);
Sie verwenden jeweils ein Argument: den keyPath
-Wert des Index für das gewünschte Element
um es als Ober- oder Untergrenze festzulegen.
Die Methode bound()
gibt sowohl eine Ober- als auch eine Untergrenze an:
IDBKeyRange.bound(lowerIndexKey, upperIndexKey);
Der Bereich für diese Funktionen ist standardmäßig inklusiv, d. h., er umfasst
die als Grenzen des Bereichs angegebenen Daten. Wenn Sie diese Werte weglassen möchten,
Sie legen den Bereich als exklusiv fest, indem Sie true
als zweites Argument für übergeben.
lowerBound()
oder upperBound()
oder als drittes und viertes Argument von
bound()
für die Unter- bzw. Obergrenze.
Im nächsten Beispiel wird ein Index für das Attribut 'price'
im 'foods'
-Objekt verwendet.
speichern. An den Store ist jetzt auch ein Formular mit zwei Eingaben für die
die Ober- und Untergrenzen des Bereichs. Verwende den folgenden Code, um Lebensmittel mit
zwischen diesen Limits liegen:
import {openDB} from 'idb';
async function searchItems (lower, upper) {
if (!lower === '' && upper === '') {
return;
}
let range;
if (lower !== '' && upper !== '') {
range = IDBKeyRange.bound(lower, upper);
} else if (lower === '') {
range = IDBKeyRange.upperBound(upper);
} else {
range = IDBKeyRange.lowerBound(lower);
}
const db = await openDB('test-db4', 1);
const tx = await db.transaction('foods', 'readonly');
const index = tx.store.index('price');
// Open a cursor on the designated object store:
let cursor = await index.openCursor(range);
if (!cursor) {
return;
}
// Iterate on the cursor, row by row:
while (cursor) {
// Show the data in the row at the current cursor position:
console.log(cursor.key, cursor.value);
// Advance the cursor to the next row:
cursor = await cursor.continue();
}
}
// Get items priced between one and four dollars:
searchItems(1.00, 4.00);
Der Beispielcode ruft zuerst die Werte für die Grenzwerte ab und prüft, ob die Grenzwerte
existieren. Der nächste Codeblock entscheidet, welche Methode zur Begrenzung des Bereichs verwendet wird.
basierend auf den Werten. Öffnen Sie in der Datenbankinteraktion den Objektspeicher auf der
Transaktion wie gewohnt und öffnen Sie dann den Index 'price'
im Objektspeicher. Die
Mit dem 'price'
-Index können Sie nach Artikeln anhand des Preises suchen.
Der Code öffnet dann einen Cursor auf dem Index und übergibt den Bereich. Der Cursor
gibt ein Promise zurück, das das erste Objekt im Bereich darstellt, oder undefined
, wenn
Der Bereich umfasst keine Daten. Die Methode cursor.continue()
gibt eine
Cursor, der das nächste Objekt darstellt, und setzt sich durch die Schleife, bis Sie
bis das Ende des Bereichs erreicht ist.
Datenbankversionsverwaltung
Wenn Sie die Methode openDB()
aufrufen, können Sie die Versionsnummer der Datenbank angeben
im zweiten Parameter. Bei allen Beispielen in diesem Handbuch wurde die Version
ist auf 1
festgelegt. Eine Datenbank kann jedoch bei Bedarf auf eine neue Version aktualisiert werden.
irgendwie verändern. Wenn die angegebene Version höher ist als die Version von
der vorhandenen Datenbank wird der Callback upgrade
im Ereignisobjekt ausgeführt,
sodass Sie der Datenbank
neue Objektspeicher und Indexe hinzufügen können.
Das db
-Objekt im upgrade
-Callback hat eine spezielle oldVersion
-Eigenschaft.
die die Versionsnummer der Datenbank angibt, auf die der Browser Zugriff hat.
Du kannst diese Versionsnummer an eine switch
-Anweisung übergeben, um Blöcke auszuführen,
Code im upgrade
-Callback basierend auf der vorhandenen Datenbankversion
Nummer. Beispiel:
import {openDB} from 'idb';
const db = await openDB('example-database', 2, {
upgrade (db, oldVersion) {
switch (oldVersion) {
case 0:
// Create first object store:
db.createObjectStore('store', { keyPath: 'name' });
case 1:
// Get the original object store, and create an index on it:
const tx = await db.transaction('store', 'readwrite');
tx.store.createIndex('name', 'name');
}
}
});
In diesem Beispiel wird die neueste Version der Datenbank auf 2
festgelegt. Wenn dieser Code
ausgeführt wird, ist die Datenbank noch nicht im Browser vorhanden, daher oldVersion
ist 0
und die switch
-Anweisung beginnt bei case 0
. In diesem Beispiel
fügt der Datenbank einen 'store'
-Objektspeicher hinzu.
Wichtig: In switch
-Anweisungen steht normalerweise ein break
nach jedem case
-Block, der hier absichtlich nicht verwendet wird. Wenn die vorhandenen
oder wenn die Datenbank nicht existiert,
wird der Code fortgesetzt.
durch die restlichen case
Blöcke, bis er auf dem neuesten Stand ist. In diesem Beispiel
Der Browser fährt mit case 1
fort und erstellt einen name
-Index auf der
store
-Objektspeicher.
Um einen 'description'
-Index im 'store'
-Objektspeicher zu erstellen, aktualisieren Sie den
Versionsnummer und fügen Sie wie folgt einen neuen case
-Block hinzu:
import {openDB} from 'idb';
const db = await openDB('example-database', 3, {
upgrade (db, oldVersion) {
switch (oldVersion) {
case 0:
// Create first object store:
db.createObjectStore('store', { keyPath: 'name' });
case 1:
// Get the original object store, and create an index on it:
const tx = await db.transaction('store', 'readwrite');
tx.store.createIndex('name', 'name');
case 2:
const tx = await db.transaction('store', 'readwrite');
tx.store.createIndex('description', 'description');
}
}
});
Wenn die im vorherigen Beispiel erstellte Datenbank noch im Browser vorhanden ist,
wenn dies ausgeführt wird, ist oldVersion
2
. Der Browser überspringt case 0
und
case 1
und führt den Code in case 2
aus, wodurch ein description
erstellt wird.
-Index. Danach hat der Browser eine Datenbank mit Version 3, die ein store
-Objekt enthält.
Objektspeicher mit name
- und description
-Indexen.
Weitere Informationen
Die folgenden Ressourcen enthalten weitere Informationen und Kontext zur Verwendung von IndexedDB.
IndexedDB-Dokumentation
idb
GitHub-Repository- IndexedDB verwenden
- Grundlegende Konzepte von IndexedDB
- Indexed Database API 3.0 – Spezifikation