Die Front-End-Datenbank der lokalen Speicherstrategie des Browsers: IndexedDB

Einführung in IndexedDB

Es gibt zwei gängige Speichermethoden: Cookie, WebStorage (localStorage und sessionStorage), aber sie sind nicht zum Speichern großer Datenmengen geeignet: Die Größe von Cookie überschreitet 4 KB nicht und jede Anfrage wird an den Server zurückgesendet; LocalStorage ist es zwischen 2,5 MB und 10 MB (jeder Browser ist anders) und bietet keine Suchfunktion und kann keinen benutzerdefinierten Index erstellen. Daher können wir die Front-End-Datenbank verwenden, um dies zu erreichen. Es gibt zwei Arten von Datenbanken im Browser: webSQL und IndexedDB.

IndexedDB ist eine vom Browser bereitgestellte lokale Datenbank, die das Speichern einer großen Datenmenge ermöglicht, eine Suchschnittstelle bereitstellt und auch einen Index erstellen kann. Diese sind in LocalStorage nicht verfügbar. Was den Datenbanktyp betrifft, ist IndexedDB keine relationale Datenbank (unterstützt keine SQL-Abfrageanweisungen), sondern näher an einer NoSQL-Datenbank.

IndexedDB hat die folgenden Eigenschaften:

  1. Schlüsselwertspeicher. IndexedDB verwendet intern einen Objektspeicher (Objektspeicher), um Daten zu speichern. Alle Arten von Daten können direkt gespeichert werden, einschließlich JavaScript-Objekte. Im Object Warehouse werden Daten in Form von „Schlüssel-Wert-Paaren" gespeichert. Jeder Datensatz hat einen zugehörigen Primärschlüssel. Der Primärschlüssel ist eindeutig und kann nicht dupliziert werden, da sonst ein Fehler geworfen wird.

  2. asynchron. IndexedDB sperrt den Browser während des Betriebs nicht, und Benutzer können weiterhin andere Operationen ausführen, im Gegensatz zu LocalStorage, dessen Operationen synchron sind. Das asynchrone Design soll das Lesen und Schreiben großer Datenmengen verhindern und die Performance von Webseiten verlangsamen.

  3. Transaktionen unterstützen. IndexedDB unterstützt Transaktionen, was bedeutet, dass, solange ein Schritt in einer Reihe von Vorgangsschritten fehlschlägt, die gesamte Transaktion abgebrochen wird und die Datenbank auf den Zustand vor der Transaktion zurückgesetzt wird und es keine Situation gibt, in der nur ein Teil der Daten wird umgeschrieben.

  4. Same-Origin-Beschränkung IndexedDB unterliegt der Same-Origin-Beschränkung, und jede Datenbank entspricht dem Domänennamen, in dem sie erstellt wurde. Eine Webseite kann nur auf Datenbanken unter ihrem eigenen Domänennamen zugreifen, nicht jedoch auf domänenübergreifende Datenbanken.

  5. Großer Speicherplatz Der Speicherplatz von IndexedDB ist viel größer als der von LocalStorage, im Allgemeinen nicht weniger als 250 MB, und es gibt sogar keine Obergrenze.

  6. Unterstützt binäre Speicherung. IndexedDB kann nicht nur Strings speichern, sondern auch binäre Daten (ArrayBuffer-Objekte und Blob-Objekte).

Einige grundlegende Konzepte von IndexedDB:

  1. Eine Datenbank, eine Datenbank ist eine Sammlung zusammengehöriger Datencontainer. Jeder Domänenname (genau genommen Protokoll + Domänenname + Port) kann beliebig viele Datenbanken erstellen. Die Datenbank IndexedDB hat ein Versionskonzept. Gleichzeitig existiert nur eine Version der Datenbank. Wenn Sie die Datenbankstruktur ändern möchten (Tabellen, Indizes oder Primärschlüssel hinzufügen oder löschen), ist dies nur durch ein Upgrade der Datenbankversion möglich.

  2. Objektspeicher, jede Datenbank enthält mehrere Objektspeicher (Objektspeicher). Es ähnelt einer Tabelle in einer relationalen Datenbank.

  3. Datensätze, das Objekt Warehouse speichert Datensätze. Jeder Datensatz ähnelt einer Zeile in einer relationalen Datenbank, besteht jedoch nur aus zwei Teilen: dem Primärschlüssel und dem Datenkörper. Der Primärschlüssel kann ein Attribut im Datensatz sein oder als aufsteigende Ganzzahl angegeben werden.

  4. Index: Nachdem Sie den Index hinzugefügt haben, können Sie den Index verwenden, um Daten abzufragen

  5. Transaktionen, Lesen, Schreiben und Löschen von Datensätzen müssen über Transaktionen erfolgen. Das Transaktionsobjekt stellt drei Fehlerereignisse bereit, Abort und Complete, die verwendet werden, um die Operationsergebnisse zu überwachen.

Die Kapselung durch Klassen kann die Lesbarkeit, Skalierbarkeit und Wartbarkeit verbessern

	//  数据库对象
    class MyDataBase {
    
    
        constructor(
            database,
            version,
            tablename
        ) {
    
    
            this.DATABASE_NAME = database;
            this.VERSION = version;
            this.TABLE = tablename;
        }
        
        //  相关数据库操作
        ...
     }

Verbinden und initialisieren Sie die Datenbank:

        /**
         * 获取数据库对象
         */
        getDB(dbName, version, table) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = window.indexedDB.open(dbName, version);
                request.onsuccess = function (e) {
    
    
                    // let db = e.target.result;
                    let db = this.result;
                    resolve(db);
                }
                request.onupgradeneeded = function (e) {
    
    
                    // 初始化数据库
                    let db = this.result;
                    if (!db.objectStoreNames.contains(table || this.TABLE)) {
    
    
                        var objectStore = db.createObjectStore(table || this.TABLE, {
    
    
                            autoIncrement: true
                        });
                        // 创建索引
                        // 可以通过索引查询
                        objectStore.createIndex("name", "name", {
    
    
                            unique: true
                        });
                        objectStore.createIndex("email", "email", {
    
    
                            unique: true
                        });
                    };
                }
            })
        }

Alle Datensätze einer Tabelle in der Datenbank abrufen:

        /**
         * 读取 [db]--[tableName] 下的所有记录
         */
        readAllRecord(db, tableName) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let objectStore = db.transaction(tableName).objectStore(tableName);
                let records = [];
                objectStore.openCursor().onsuccess = function (e) {
    
    
                    let cursor = e.target.result;
                    if (cursor) {
    
    
                        records.push(cursor.value);
                        cursor.continue();
                    } else {
    
    
                        resolve({
    
    
                            code: 200,
                            data: records
                        })
                    }
                }
                objectStore.openCursor().onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

Finden Sie ein Datenelement (entsprechend dem Primärschlüssel der Datenbanktabelle):

        /**
         * 获取 [db]--[tableName]下,主键为 [key] 的某条记录
         */
        getRecord(db, tableName, key) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName)
                    .objectStore(tableName)
                    .get(key);
                request.onsuccess = function (e) {
    
    
                    resolve({
    
    
                        code: 200,
                        data: e.target.result
                    });
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

Daten nach Index suchen:

        /**
         * 根据索引所在位置 [_index],获取 [db]--[tableName]下,索引值为 [identify]的某条记录
         */
        getRecordWithIndex(db, tableName, _index, identify) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName, "readwrite")
                    .objectStore(tableName)
                    .index(_index)
                    .get(identify);
                request.onsuccess = function (e) {
    
    
                    resolve({
    
    
                        code: 200,
                        data: e.target.result
                    });
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

Fügen Sie einer datenbankspezifischen Tabelle ein Datenelement hinzu:

        /**
         * 在 [db]--[tableName]中新增一条记录[data]
         */
        addRecord(db, tableName, data) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName, "readwrite")
                    .objectStore(tableName)
                    .add(data);
                request.onsuccess = function () {
    
    
                    resolve({
    
    
                        code: 200
                    });
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

Ändern Sie ein Datenelement (gemäß dem Primärschlüssel):

        /**
         * 将 [db]--[tableName]中,主键为 [key]的数据为,更新为 [data]
         */
        updateRecord(db, tableName, data, key) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName, "readwrite")
                    .objectStore(tableName)
                    .put(data, key);
                request.onsuccess = function () {
    
    
                    resolve({
    
    
                        code: 200
                    })
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

Löschen Sie ein Datenelement (gemäß dem Primärschlüssel):

        /**
         * 在 [db]--[tableName]下,删除主键为[key]的记录
         */
        deleteRecord(db, tableName, key) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName, "readwrite")
                    .objectStore(tableName)
                    .delete(key);
                request.onsuccess = function () {
    
    
                    resolve({
    
    
                        code: 200
                    });
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

Vollständiger Code:

	//  数据库对象
    class MyDataBase {
    
    
        constructor(
            database,
            version,
            tablename
        ) {
    
    
            this.DATABASE_NAME = database;
            this.VERSION = version;
            this.TABLE = tablename;
        }

        /**
         * 在 [db]--[tableName]中新增一条记录[data]
         */
        addRecord(db, tableName, data) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName, "readwrite")
                    .objectStore(tableName)
                    .add(data);
                request.onsuccess = function () {
    
    
                    resolve({
    
    
                        code: 200
                    });
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

        /**
         * 获取 [db]--[tableName]下,主键为 [key] 的某条记录
         */
        getRecord(db, tableName, key) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName)
                    .objectStore(tableName)
                    .get(key);
                request.onsuccess = function (e) {
    
    
                    resolve({
    
    
                        code: 200,
                        data: e.target.result
                    });
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

        /**
         * 根据索引所在位置 [_index],获取 [db]--[tableName]下,索引值为 [identify]的某条记录
         */
        getRecordWithIndex(db, tableName, _index, identify) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName, "readwrite")
                    .objectStore(tableName)
                    .index(_index)
                    .get(identify);
                request.onsuccess = function (e) {
    
    
                    resolve({
    
    
                        code: 200,
                        data: e.target.result
                    });
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

        /**
         * 读取 [db]--[tableName] 下的所有记录
         */
        readAllRecord(db, tableName) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let objectStore = db.transaction(tableName).objectStore(tableName);
                let records = [];
                objectStore.openCursor().onsuccess = function (e) {
    
    
                    let cursor = e.target.result;
                    if (cursor) {
    
    
                        records.push(cursor.value);
                        cursor.continue();
                    } else {
    
    
                        resolve({
    
    
                            code: 200,
                            data: records
                        })
                    }
                }
                objectStore.openCursor().onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

        /**
         * 将 [db]--[tableName]中,主键为 [key]的数据为,更新为 [data]
         */
        updateRecord(db, tableName, data, key) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName, "readwrite")
                    .objectStore(tableName)
                    .put(data, key);
                request.onsuccess = function () {
    
    
                    resolve({
    
    
                        code: 200
                    })
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

        /**
         * 在 [db]--[tableName]下,删除主键为[key]的记录
         */
        deleteRecord(db, tableName, key) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = db.transaction(tableName, "readwrite")
                    .objectStore(tableName)
                    .delete(key);
                request.onsuccess = function () {
    
    
                    resolve({
    
    
                        code: 200
                    });
                }
                request.onerror = function (e) {
    
    
                    reject({
    
    
                        code: 0,
                        msg: e.target.error
                    })
                }
            })
        }

        /**
         * 获取数据库对象
         */
        getDB(dbName, version, table) {
    
    
            return new Promise(function (resolve, reject) {
    
    
                let request = window.indexedDB.open(dbName, version);
                request.onsuccess = function (e) {
    
    
                    // let db = e.target.result;
                    let db = this.result;
                    resolve(db);
                }
                request.onupgradeneeded = function (e) {
    
    
                    // 初始化数据库
                    let db = this.result;
                    if (!db.objectStoreNames.contains(table || this.TABLE)) {
    
    
                        var objectStore = db.createObjectStore(table || this.TABLE, {
    
    
                            autoIncrement: true
                        });
                        // 创建索引
                        // 可以通过索引查询
                        objectStore.createIndex("name", "name", {
    
    
                            unique: true
                        });
                        objectStore.createIndex("email", "email", {
    
    
                            unique: true
                        });
                    };
                }
            })
        }
    }

    // 数据库连接信息
    const connection = {
    
    
        database: 'my_database',
        version: '1.0',
        tablename: 'table_user'
    }
    // 获取数据库对象
    const database = new MyDataBase(
        connection.database,
        connection.version,
        connection.tablename
    );

    database.getDB(connection.database, connection.version, connection.tablename).then(db => {
    
    
        let data = {
    
    
            id: 1,
            name: "张三",
            age: 18,
            email: "[email protected]"
        }

        let data1 = {
    
    
            id: 2,
            name: "张三22",
            age: 18,
            email: "[email protected]"
        }

        database.addRecord(db, connection.tablename, data).then(res => {
    
    
            console.log(res);
        }, err => {
    
    
            console.log(err);
        })

        database.addRecord(db, connection.tablename, data1).then(res => {
    
    
            console.log(res);
        }, err => {
    
    
            console.log(err);
        })

        database.readAllRecord(db, connection.tablename).then(res => {
    
    
            console.log(res);
        }, err => {
    
    
            console.log(err);
        })

        // 根据数据库存储数据的主键来查找某一条数据
        database.getRecord(db, connection.tablename, 1).then(res => {
    
    
            console.log(res);
        }, err => {
    
    
            console.log(err);
        })

        // 根据索引为email字段,并且索引值为[email protected] 来查找数据
        database.getRecordWithIndex(db, connection.tablename, "email", "[email protected]").then(res => {
    
    
            console.log(res);
        }, err => {
    
    
            console.log(err);
        })

        database.updateRecord(db, connection.tablename, {
    
     id: 1, name: "李四", age: 18, email: "[email protected]" }, 1).then(res => {
    
    
            console.log(res);
        }, err => {
    
    
            console.log(err);
        })

        database.deleteRecord(db, connection.tablename, 1).then(res => {
    
    
            console.log(res);
        }, err => {
    
    
            console.log(err);
        })

    })

Guess you like

Origin blog.csdn.net/xiaorunye/article/details/130037694