Start · Sprachen · JavaScript · Referenz · IDBObjectStore

IDBObjectStore

Schnittstelle

Repräsentiert einen Objektspeicher einer IndexedDB-Datenbank, über den Datensätze per Schlüssel gelesen, geschrieben, gelöscht und über Indizes abgefragt werden.

seit JavaScript Baseline: alle Browser (IndexedDB 2.0; getAll/getA Kategorie: webapi

Signatur

interface IDBObjectStore

Beschreibung

Das Interface IDBObjectStore steht für einen einzelnen Objektspeicher innerhalb einer IndexedDB-Datenbank – vergleichbar mit einer Tabelle in einer relationalen Datenbank. Jeder Datensatz besteht aus einem Schlüssel und einem Wert. Der Wert kann jedes per Structured Clone kopierbare Objekt sein (Objekte, Arrays, Date, Blob, Map usw.).

Objektspeicher legt man ausschließlich im upgradeneeded-Ereignis über IDBDatabase.createObjectStore() an. Danach kommt man über eine Transaktion an sie heran: db.transaction("name", "readwrite").objectStore("name"). Wichtige Eigenschaften sind name, keyPath, autoIncrement, indexNames und transaction.

Die wichtigsten Methoden:

  • add(value, key?) fügt einen Datensatz ein und schlägt fehl, wenn der Schlüssel schon existiert. put(value, key?) fügt ein oder überschreibt.
  • get(key), getAll(query?, count?), getKey(), getAllKeys() und count() lesen Daten.
  • delete(keyOrRange) und clear() löschen Datensätze.
  • openCursor() / openKeyCursor() laufen über Datensätze, auf Wunsch eingeschränkt durch ein IDBKeyRange.
  • createIndex(), deleteIndex() (nur während eines Upgrades) und index(name) verwalten und nutzen sekundäre Indizes.

Alle Datenoperationen arbeiten asynchron und geben ein IDBRequest zurück. Das Ergebnis steht nach dem Ereignis success in request.result, Fehler kommen über error. Es gibt keinen Konstruktor, Instanzen bekommt man nur über createObjectStore() oder IDBTransaction.objectStore().

Parameter

Name Typ Default Beschreibung
$value Pflicht any Bei add()/put(): der zu speichernde Wert. Er muss per Structured Clone kopierbar sein, Funktionen und DOM-Knoten gehen also nicht.
$key IDBValidKey Bei add()/put(): ein expliziter Schlüssel. Er ist nicht erlaubt, wenn der Store einen keyPath hat, und Pflicht, wenn der Store weder keyPath noch autoIncrement hat.
$query IDBValidKey | IDBKeyRange Bei get(), getAll(), delete(), count() und openCursor(): ein einzelner Schlüssel oder ein Schlüsselbereich.
$count number unbegrenzt Bei getAll()/getAllKeys(): die maximale Anzahl der gelieferten Datensätze.
$direction "next" | "nextunique" | "prev" | "prevunique" "next" Bei openCursor()/openKeyCursor(): die Laufrichtung des Cursors.
$indexName, keyPath, options string, string | string[], { unique?: boolean, multiEntry?: boolean } Bei createIndex(): Name des Index, Pfad der indizierten Eigenschaft und Optionen (Eindeutigkeit, ein Indexeintrag je Array-Element).

Rückgabewert

Typ
IDBRequest
Beschreibung
Datenmethoden geben ein IDBRequest zurück, dessen result nach success das Ergebnis enthält (Wert, Schlüssel, Array, Anzahl oder IDBCursorWithValue). index() und createIndex() geben direkt einen IDBIndex zurück.

Beispiele

Objektspeicher mit Index beim Upgrade anlegen

const openDb = () => new Promise((resolve, reject) => {
  const req = indexedDB.open("shop", 1);
  req.onupgradeneeded = () => {
    const db = req.result;
    // Objektspeicher mit keyPath und automatischem Schlüssel
    const store = db.createObjectStore("products", { keyPath: "id", autoIncrement: true });
    store.createIndex("by_sku", "sku", { unique: true });
    store.createIndex("by_tags", "tags", { multiEntry: true });
    console.log(store.name, store.keyPath, [...store.indexNames]);
  };
  req.onsuccess = () => resolve(req.result);
  req.onerror = () => reject(req.error);
});

const db = await openDb();
products id ["by_sku", "by_tags"]

Datensätze mit add, put und get bearbeiten (Promise-Hilfsfunktion)

const promisify = (req) => new Promise((resolve, reject) => {
  req.onsuccess = () => resolve(req.result);
  req.onerror = () => reject(req.error);
});

const tx = db.transaction("products", "readwrite");
const store = tx.objectStore("products");

const id = await promisify(store.add({ sku: "A-100", name: "Tasse", price: 9.9, tags: ["küche"] }));
await promisify(store.put({ id, sku: "A-100", name: "Tasse", price: 7.9, tags: ["küche", "sale"] }));
const product = await promisify(store.get(id));
console.log(id, product.price);

// Warten, bis die Transaktion abgeschlossen ist
await new Promise((res, rej) => { tx.oncomplete = res; tx.onerror = () => rej(tx.error); });
1 7.9

Über Index und Cursor abfragen

const store = db.transaction("products").objectStore("products");

// Alle Produkte mit dem Tag "sale" über den Index
const saleReq = store.index("by_tags").getAll("sale");
saleReq.onsuccess = () => console.log("Im Angebot:", saleReq.result.length);

// Cursor über die IDs 1 bis 100, absteigend
const cursorReq = store.openCursor(IDBKeyRange.bound(1, 100), "prev");
cursorReq.onsuccess = () => {
  const cursor = cursorReq.result;
  if (!cursor) return console.log("fertig");
  console.log(cursor.key, cursor.value.name);
  cursor.continue();
};
Im Angebot: 1 1 Tasse fertig

Bereich löschen und Einträge zählen

const tx = db.transaction("products", "readwrite");
const store = tx.objectStore("products");

store.delete(IDBKeyRange.lowerBound(50)); // alle IDs ab 50
const countReq = store.count();
countReq.onsuccess = () => console.log("Verbleibend:", countReq.result);
Verbleibend: 1