Greitas, bet išsamus „IndexedDB“ ir duomenų saugojimo naršyklėse vadovas

Norite sužinoti „JavaScript“? Gaukite nemokamą el. Knygą svetainėje jshandbook.com

„IndexedDB“ yra viena iš saugojimo galimybių, per daugelį metų įdiegtų naršyklėse. Tai raktų / reikšmių saugykla („NoSQL“ duomenų bazė), laikoma galutiniu duomenų saugojimo naršyklėse sprendimu.

„IndexedDB“ yra asinchroninė API, tai reiškia, kad atlikdami brangias operacijas neužblokuosite vartotojo sąsajos gijos, teikiančios vartotojams neapykantą.

Jis gali saugoti neribotą kiekį duomenų, nors peržengus tam tikrą ribą, vartotojui siūloma suteikti svetainei aukštesnes ribas.

Jis palaikomas visose šiuolaikinėse naršyklėse.

Tai palaiko operacijas ir versijas bei teikia gerus rezultatus.

Naršyklėje taip pat galime naudoti:

  • Slapukai, kuriuose gali būti labai mažas stygų skaičius
  • DOM saugykla (arba žiniatinklio saugykla) - terminas, paprastai identifikuojantis „localStorage“ ir „sessionStorage“, dvi raktų / vertės saugyklas. sessionStorage neišsaugo duomenų, kurie išvalomi pasibaigus sesijai, o „localStorage“ saugo duomenis per visus seansus

Vietinės / sesijos saugyklos trūkumas yra tas, kad ji yra maža (ir nenuosekli), nes naršyklių įdiegimas siūlo nuo 2 MB iki 10 MB vietos svetainėje.

Anksčiau mes taip pat turėjome žiniatinklio SQL, aplanką aplink SQLite. Bet dabar tai nebeaktualu ir nepalaikoma kai kuriose šiuolaikinėse naršyklėse. Jis niekada nebuvo pripažintas standartas, todėl jo nereikėtų naudoti - nors 83 proc. Vartotojų turi šią technologiją savo įrenginiuose pagal „Aš galiu naudoti“ principą.

Nors galite techniškai sukurti kelias duomenų bazes vienoje svetainėje, paprastai sukuriate vieną duomenų bazę. Toje duomenų bazėje galite sukurti kelias objektų saugyklas.

Duomenų bazė yra privati ​​domenui, todėl bet kuri kita svetainė negali pasiekti kitos svetainės „IndexedDB“ parduotuvių.

Kiekvienoje parduotuvėje paprastai yra daiktų rinkinys, kuris gali būti:

  • stygos
  • skaičiai
  • daiktai
  • masyvai
  • datos

Pvz., Galite turėti parduotuvę, kurioje yra įrašų, ir kitą, kurioje yra komentarų.

Parduotuvėje yra keletas elementų, turinčių unikalų raktą, kuris nurodo būdą, kuriuo galima identifikuoti objektą.

Šias parduotuves galite pakeisti naudodami operacijas, atlikdami pridėjimo, redagavimo ir ištrynimo operacijas ir pakartodami joje esančius elementus.

Nuo pat pažadų atsiradimo ES2015 ir vėlesnio API perėjimo prie pažadų naudojimo, „IndexedDB“ API atrodo šiek tiek sena mokykla.

Nors čia nėra nieko blogo, visuose paaiškintuose pavyzdžiuose naudoju Jake Archibald indeksuotą DB pažadėtą ​​biblioteką, kuri yra maža „IndexedDB API“ API viršuje, kad būtų lengviau naudoti.

Ši biblioteka taip pat naudojama visuose „Google Developers“ svetainės pavyzdžiuose, susijusiuose su „IndexedDB“.

Sukurkite „IndexedDB“ duomenų bazę

Įtraukite „idb lib“ naudodami:

siūlai pridėti idb

Ir tada įtraukite jį į savo puslapį naudodami „Webpack“ arba „Browserify“ ar bet kurią kitą kaupimo sistemą arba tiesiog:

 

Ir mes pasiruošę eiti.

Prieš naudodamiesi „IndexedDB API“, būtinai patikrinkite, ar naršyklėje palaikoma, net jei ji yra plačiai prieinama. Niekada negali žinoti, kurią naršyklę vartotojas naudoja:

(() => {
  'naudoti griežtai'
  if (! ('indeksuotasDB' lange)) {
    console.warn ('IndexedDB nepalaikomas')
    grįžti
  }
//...IndexedDB kodas
}) ()

Kaip sukurti duomenų bazę

Naudojant idb.open ():

const name = 'mydbname'
const versija = 1 // versijos prasideda nuo 1
idb.open (vardas, versija, atnaujinimoDb => {})

Pirmieji du parametrai yra savaime suprantami. Trečiasis parametras, kuris yra neprivalomas, yra atgalinis skambutis, tik jei versijos numeris yra didesnis nei dabartinė įdiegta duomenų bazės versija. Atgalinio skambinimo funkcijos tekste galite atnaujinti db struktūrą (atsargas ir rodykles).

Atšaukimui naudojame pavadinimą „upgradeDB“, kad nustatytume, jog reikia laiko atnaujinti duomenų bazę.

Sukurkite objektų parduotuvę

Kaip sukurti objektų parduotuvę arba pridėti naują

Objektų saugykla sukuriama arba atnaujinama per šį atgalinį ryšį, naudojant db.createObjectStore ('storeName', parinktys) sintaksę:

const dbPromise = idb.open ('mydb', 1, (atnaujinimoDB) => {
  upgradeDB.createObjectStore ('parduotuvė1')
})
. Tada (db => console.log ('sėkmė'))

Jei įdiegėte ankstesnę versiją, atgalinis ryšys leidžia atlikti perkėlimą:

const dbPromise = idb.open ('keyval-store', 3, (atnaujinimoDB) => {
  jungiklis (upgradeDB.oldVersion) {
    0 atvejis: // anksčiau nebuvo sukurta db
      // parduotuvė, pristatyta 1 versijoje
      upgradeDB.createObjectStore ('parduotuvė1')
    1 atvejis:
      // nauja 2 versijos parduotuvė
      upgradeDB.createObjectStore ('store2', {keyPath: 'name'})
  }
})
. Tada (db => console.log ('sėkmė'))

createObjectStore (), kaip matote 1 atveju, priima antrą parametrą, nurodantį duomenų bazės indekso raktą. Tai labai naudinga, kai saugote objektus: put () skambučiams nereikia antro parametro, bet gali tiesiog pasiimti reikšmę (objektą), o raktas bus susietas su objekto ypatybe, kuri turi tokį pavadinimą.

Rodyklė suteikia jums būdą vėliau nuskaityti reikšmę tuo konkrečiu raktu, ir ji turi būti unikali (kiekvienas elementas turi turėti skirtingą raktą).

Raktą galima nustatyti kaip automatinį didėjimą, todėl jums nereikia sekti jo kliento kode. Jei nenurodysite rakto, „IndexedDB“ mums jį sukurs skaidriai:

upgradeDb.createObjectStore („pastabos“, {autoIncrement: true})

bet taip pat galite nurodyti ir konkretų objekto vertės lauką, kad jis būtų automatiškai didinamas:

upgradeDb.createObjectStore („pastabos“, {
  „keyPath“: „id“,
  autoIncrement: tiesa
})

Paprastai naudokite automatinį didėjimą, jei jūsų vertėse jau nėra unikalaus rakto (pavyzdžiui, el. Pašto adresas vartotojams).

Rodyklės

Rodyklė yra būdas nuskaityti duomenis iš objektų saugyklos. Tai apibrėžta kartu su duomenų bazės sukūrimu „idb.open ()“ atgaliniame skambutyje tokiu būdu:

const dbPromise = idb.open ('dogsdb', 1, (atnaujintiDB) => {
  const šunys = upgradeDB.createObjectStore ('šunys')
  dogs.createIndex („vardas“, „vardas“, {unikalus: klaidingas})
})

Unikali parinktis nustato, ar indekso reikšmė turėtų būti unikali, ir neleidžiama dėti pasikartojančių verčių.

Jau pasiektą objektų saugyklą galite pasiekti naudodami metodą „upgradeDb.transaction.objectStore ()“:

const dbPromise = idb.open ('dogsdb', 1, (atnaujintiDB) => {
  const šunys = upgradeDB.transaction.objectStore („šunys“)
  dogs.createIndex („vardas“, „vardas“, {unikalus: klaidingas})
})

Patikrinkite, ar nėra parduotuvės

Galite patikrinti, ar objektų saugykla jau egzistuoja, paskambinę „objectStoreNames ()“ metodu:

if (! upgradeDb.objectStoreNames.contains ('store3')) {
  „upgradeDb.createObjectStore“ („store3“)
}

Ištrinama iš „IndexedDB“

Ištrinkite duomenų bazę

idb.delete ('mydb'). tada (() => console.log ('done'))

Ištrinkite objektų saugyklą

Objektų saugyklą ištrynimo metu galima ištrinti tik atidarius db, o atgalinis skambutis gali būti iškviečiamas tik tuo atveju, jei nurodote aukštesnę nei šiuo metu įdiegtą versiją:

const dbPromise = idb.open ('dogsdb', 2, (atnaujintiDB) => {
  upgradeDB.deleteObjectStore ('old_store')
})

Norėdami ištrinti duomenis objektų parduotuvėje, naudokite šią operaciją:

const klavišas = 232
dbPromise.then ((db) => {
  const tx = db.transaction („laikyti“, „skaityti“)
  „const store = tx.objectStore“ („parduotuvė“)
  store.delete (raktas)
  grąžinti tx.complete
})
. Tada (() => {
  console.log ('Elementas ištrintas')
})

Pridėti elementą į duomenų bazę

Galite naudoti objektų saugyklos put metodą, tačiau pirmiausia mums reikia nuorodos į jį, kurį mes galime gauti iš atnaujinimoDB.createObjectStore (), kai jį sukuriame.

Naudojant put, reikšmė yra pirmasis argumentas, o raktas yra antrasis. Taip yra todėl, kad kurdami objektų saugyklą nurodėte „keyPath“, jums nereikia įvesti rakto pavadinimo kiekvienoje „put ()“ užklausoje. Galite tiesiog parašyti vertę.

Tai išpopuliarėja parduotuvėje0, kai tik ją sukuriame:

idb.open ('mydb', 1, (atnaujinimoDB) => {
  keyValStore = upgradeDB.createObjectStore ('store0')
  „keyValStore.put“ („Sveikas pasaulis!“, „Sveiki“)
})

Jei norite vėliau pridėti elementų, turite sukurti operaciją. Tai užtikrina duomenų bazės vientisumą (jei operacija nepavyksta, visos operacijos operacijos atšaukiamos, o būsena grįžta į žinomą būseną).

Tam naudokite nuorodą į objektą dbPromise, kurį gavome skambindami idb.open (), ir paleiskite:

dbPromise.then ((db) => {
  const val = 'Ei!'
  „const“ klavišas = 'Sveiki dar kartą'
  const tx = db.transaction („parduotuvė1“, „skaitymo knyga“)
  tx.objectStore ('parduotuvė1'). įdėti (val, raktas)
  grąžinti tx.complete
})
. Tada (() => {
  console.log („Operacija baigta“)
})
.catch (() => {
  console.log („Operacija nepavyko“)
})

Indeksuota DB API taip pat siūlo metodą „add ()“, tačiau kadangi įdėjimas () leidžia mums ir pridėti, ir atnaujinti, paprasčiau jį naudoti.

Daiktų gavimas iš parduotuvės

Konkrečios prekės gavimas iš parduotuvės naudojant „get“ ()

dbPromise.then (db => db.transaction ('objs')
                       .objectStore („objs“)
                       .get (123456))
. Tada (obj => console.log (obj))

Visų elementų gavimas naudojant „getAll“ ()

dbPromise.then (db => db.transaction („parduotuvė1“)
                       .objectStore („parduotuvė1“)
                       .getAll ())
. Tada (objektai => console.log (objektai))

Visų elementų pakartojimas naudojant žymeklį per „openCursor“ ()

dbPromise.then ((db) => {
  const tx = db.transaction („laikyti“, „tik skaityti“)
  „const store = tx.objectStore“ („parduotuvė“)
  grąžinti parduotuvę.openCursor ()
})
.then (funkcijos logItems (žymeklis) {
  if (! žymeklis) {grįžti}
  console.log ('žymeklis yra:', cursor.key)
  for (const laukas cursor.value) {
    console.log (cursor.value [laukas])
  }
  grįžti žymeklį.tęsti (). tada (logItems)
})
. Tada (() => {
  console.log („padaryta!“)
})

Iteravimas elementų pogrupyje naudojant ribas ir žymeklius

const searchItems = (apatinė, viršutinė) => {
  if (apatinė === '' && viršutinė === '') {return}
  tegul diapazonas
  if (apatinė! == '' && viršutinė! == '') {
    diapazonas = IDBKeyRange.siribojama (apatinė, viršutinė)
  } else if (apatinis === '') {
    diapazonas = IDBKeyRange.upperBound (viršutinė)
  } Kitas {
    diapazonas = IDBKeyRange.lowerBound (apatinis)
  }
  dbPromise.then ((db) => {
    const tx = db.transaction (['šunys'], 'tik skaityti')
    „const store“ = tx.objectStore („šunys“)
    const index = store.index ('amžius')
    grąžinti rodyklę.openCursor (diapazonas)
  })
  . Tada (funkcija showRange (žymeklis) {
    if (! žymeklis) {grįžti}
    console.log ('žymeklis yra:', cursor.key)
    for (const laukas cursor.value) {
      console.log (cursor.value [laukas])
    }
    grįžti žymeklį.tęsti (). tada (showRange)
  })
  . Tada (() => {
    console.log („padaryta!“)
  })
}
paieškaŠunysBetweenAges (3, 10)
Norite sužinoti „JavaScript“? Gaukite nemokamą el. Knygą svetainėje jshandbook.com