Ātrs, bet pilnīgs IndexedDB ceļvedis un datu glabāšana pārlūkprogrammās

Vai vēlaties uzzināt JavaScript? Iegūstiet manu JavaScript ebook vietnē jshandbook.com

Ievads IndexedDB

IndexedDB ir viena no krātuves iespējām, kas gadu gaitā ieviesta pārlūkprogrammās.

Tas ir atslēgu / vērtību krājums (noSQL datu bāze), kas tiek uzskatīts par galīgo risinājumu datu glabāšanai pārlūkprogrammās .

Tas ir asinhronais API, kas nozīmē, ka dārgu darbību veikšana neaizkavēs lietotāja saskarnes pavedienu, nodrošinot lietotājiem paviršu pieredzi. Tas var uzglabāt nenoteiktu datu daudzumu, lai gan, pārsniedzot noteiktu slieksni, lietotājs tiek aicināts vietnei noteikt augstākas robežas.

To atbalsta visas mūsdienu pārlūkprogrammas.

Tas atbalsta darījumus, versiju veidošanu un nodrošina labu sniegumu.

Pārlūkprogrammā mēs varam izmantot arī:

  • Sīkdatnes : var uzņemt ļoti nelielu virkņu daudzumu
  • Tīmekļa krātuve (vai DOM krātuve) - termins, kas parasti identificē vietniStorage un sessionStorage - divus atslēgu / vērtību krājumus. sessionStorage, nesaglabā datus, kas tiek notīrīti, kad sesija beidzas, savukārt localStorage glabā datus visu sesiju laikā

Vietējās / sesijas krātuvei ir trūkums, jo to ierobežo mazs (un pretrunīgs) lielums, un pārlūkprogrammas ieviešana piedāvā no 2 MB līdz 10 MB vietas katrā vietnē.

Agrāk mums bija arī Web SQL , aptinums ap SQLite, taču tagad tas ir novecojis un netiek atbalstīts dažās mūsdienu pārlūkprogrammās, tas nekad nav bijis atzīts standarts, un tāpēc to nevajadzētu izmantot, lai gan šī tehnoloģija ir 83% lietotāju. ierīces saskaņā ar Can I Use.

Kaut arī tehniski vienā vietnē varat izveidot vairākas datu bāzes, parasti izveidojat vienu datu bāzi , un šīs datu bāzes iekšpusē varat izveidot vairākus objektu veikalus .

Datu bāze ir privāta domēnam , tāpēc jebkura cita vietne nevar piekļūt citai vietnei IndexedDB veikalos.

Katrā veikalā parasti ir lietu kopums , kas var būt

  • stīgas
  • numurus
  • objektiem
  • masīvi
  • datumiem

Piemēram, jums var būt veikals, kurā ir ziņas, citā - komentāri.

Veikalā ir vairākas preces, kurām ir unikāla atslēga, kas norāda veidu, kā objektu var identificēt.

Varat mainīt šos veikalus, izmantojot darījumus, veicot pievienošanas, rediģēšanas un dzēšanas darbības un atkārtojot tajos esošos vienumus.

Kopš solījumu parādīšanās ES6 un turpmākās API pārejas uz solījumu izmantošanu, IndexedDB API šķiet mazliet veca skola .

Lai gan tajā nav nekā nepareiza, visos piemēros, kurus es paskaidrošu, es izmantošu Jake Archibald IndexedDB Promised Library, kas ir niecīgs slānis virs IndexedDB API, lai atvieglotu tā lietošanu.

Šī bibliotēka tiek izmantota arī visos Google Developers vietnes piemēros saistībā ar IndexedDB

Izveidojiet IndexedDB datu bāzi

Vienkāršākais veids ir izmantot unpkg , pievienojot to lapas galvenei:

 import { openDB, deleteDB } from '//unpkg.com/idb?module'  

Pirms lietojat IndexedDB API, vienmēr pārbaudiet, vai pārlūkprogrammā tiek atbalstīts atbalsts, kaut arī tas ir plaši pieejams, nekad nevar zināt, kuru pārlūkprogrammu lietotājs izmanto:

(() => { 'use strict' if (!('indexedDB' in window)) { console.warn('IndexedDB not supported') return } //...IndexedDB code })() 

izveidot datu bāzi

Izmantojot openDB():

(async () => { //... const dbName = 'mydbname' const storeName = 'store1' const version = 1 //versions start at 1 const db = await openDB(dbName, version, { upgrade(db, oldVersion, newVersion, transaction) { const store = db.createObjectStore(storeName) } }) })() 

Pirmie 2 parametri ir datu bāzes nosaukums un verson. Trešais parametrs, kas nav obligāts, ir objekts, kas satur funkciju, kuru izsauc tikai tad, ja versijas numurs ir lielāks par pašreizējo instalētās datu bāzes versiju . Funkcijas pamattekstā jūs varat uzlabot db struktūru (veikalus un indeksus).

Datu pievienošana veikalā

Datu pievienošana, kad tiek izveidots veikals, inicializējot tos

Jūs izmantojat putobjektu veikala metodi, bet vispirms mums ir nepieciešama atsauce uz to, kuru mēs varam iegūt db.createObjectStore(), to izveidojot.

Lietojot put, vērtība ir pirmais arguments, galvenais ir otrais. Tas ir tāpēc, ka, norādot keyPath, veidojot objektu krātuvi, katrā put () pieprasījumā nav jāievada atslēgas nosaukums, jūs varat vienkārši ierakstīt vērtību.

Tas tiek aizpildīts store0, tiklīdz mēs to izveidojam:

(async () => { //... const dbName = 'mydbname' const storeName = 'store0' const version = 1 const db = await openDB(dbName, version,{ upgrade(db, oldVersion, newVersion, transaction) { const store = db.createObjectStore(storeName) store.put('Hello world!', 'Hello') } }) })() 

Datu pievienošana, kad veikals jau ir izveidots, izmantojot darījumus

Lai vēlāk pievienotu vienumus pa ceļu, jāizveido lasīšanas / rakstīšanas transakcija , kas nodrošina datu bāzes integritāti (ja darbība neizdodas, visas operācijas operācijas tiek atceltas un stāvoklis atgriežas zināmā stāvoklī).

Lai to izdarītu, izmantojiet atsauci uz dbPromiseobjektu, kuru saņēmām, zvanot openDB, un palaidiet:

(async () => { //... const dbName = 'mydbname' const storeName = 'store0' const version = 1 const db = await openDB(/* ... */) const tx = db.transaction(storeName, 'readwrite') const store = await tx.objectStore(storeName) const val = 'hey!' const key = 'Hello again' const value = await store.put(val, key) await tx.done })() 

Datu iegūšana no veikala

Vienas preces iegūšana no veikala: get()

const key = 'Hello again' const item = await db.transaction(storeName).objectStore(storeName).get(key) 

Visu preču iegūšana no veikala: getAll()

Iegūstiet visas atslēgas

const items = await db.transaction(storeName).objectStore(storeName).getAllKeys() 

Iegūstiet visas saglabātās vērtības

const items = await db.transaction(storeName).objectStore(storeName).getAll() 

Datu dzēšana no IndexedDB

Datu bāzes, objektu krātuves un datu dzēšana

Dzēst visu IndexedDB datu bāzi

const dbName = 'mydbname' await deleteDB(dbName) 

Lai dzēstu datus objektu veikalā

Mēs izmantojam darījumu:

(async () => { //... const dbName = 'mydbname' const storeName = 'store1' const version = 1 const db = await openDB(dbName, version, { upgrade(db, oldVersion, newVersion, transaction) { const store = db.createObjectStore(storeName) } }) const tx = await db.transaction(storeName, 'readwrite') const store = await tx.objectStore(storeName) const key = 'Hello again' await store.delete(key) await tx.done })() 

Migrēt no iepriekšējās datubāzes versijas

The third (optional) parameter of the openDB() function is an object that can contain an upgrade function called only if the version number is higher than the current installed database version. In that function body you can upgrade the structure (stores and indexes) of the db:

const name = 'mydbname' const version = 1 openDB(name, version, { upgrade(db, oldVersion, newVersion, transaction) { console.log(oldVersion) } }) 

In this callback, you can check from which version the user is updating, and perform some operations accordingly.

You can perform a migration from a previous database version using this syntax

(async () => { //... const dbName = 'mydbname' const storeName = 'store0' const version = 1 const db = await openDB(dbName, version, { upgrade(db, oldVersion, newVersion, transaction) { switch (oldVersion) { case 0: // no db created before // a store introduced in version 1 db.createObjectStore('store1') case 1: // a new store in version 2 db.createObjectStore('store2', { keyPath: 'name' }) } db.createObjectStore(storeName) } }) })() 

Unique keys

createObjectStore() as you can see in case 1 accepts a second parameter that indicates the index key of the database. This is very useful when you store objects: put() calls don't need a second parameter, but can just take the value (an object) and the key will be mapped to the object property that has that name.

The index gives you a way to retrieve a value later by that specific key, and it must be unique (every item must have a different key)

A key can be set to auto increment, so you don't need to keep track of it on the client code:

db.createObjectStore('notes', { autoIncrement: true }) 

Use auto increment if your values do not contain a unique key already (for example, if you collect email addresses without an associated name).

Check if a store exists

You can check if an object store already exists by calling the objectStoreNames() method:

const storeName = 'store1' if (!db.objectStoreNames.contains(storeName)) { db.createObjectStore(storeName) } 

Deleting from IndexedDB

Deleting the database, an object store and data

Delete a database

await deleteDB('mydb') 

Delete an object store

An object store can only be deleted in the callback when opening a db, and that callback is only called if you specify a version higher than the one currently installed:

const db = await openDB('dogsdb', 2, { upgrade(db, oldVersion, newVersion, transaction) { switch (oldVersion) { case 0: // no db created before // a store introduced in version 1 db.createObjectStore('store1') case 1: // delete the old store in version 2, create a new one db.deleteObjectStore('store1') db.createObjectStore('store2') } } }) 

To delete data in an object store use a transaction

const key = 232 //a random key const db = await openDB(/*...*/) const tx = await db.transaction('store', 'readwrite') const store = await tx.objectStore('store') await store.delete(key) await tx.complete 

There's more!

Tie ir tikai pamati. Es nerunāju par kursoriem un progresīvākām lietām. Ir vēl vairāk IndexedDB, bet es ceru, ka tas jums palīdzēs.

Vai vēlaties uzzināt JavaScript? Iegūstiet manu JavaScript grāmatu vietnē jshandbook.com