167
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

IndexedDBの使い方

IndexedDBを使うと、ブラウザ内にWebStorageより大量のデータを保存できます。

ただし、ブラウザのプライバシーモードでは使えない場合があります。
2019年1月現在、主要ブラウザでプライバシーモードでも使えるのはChromeのみです。(ブラウザ実装状況)

IE11では、ローカルにファイルを置いてfile://urlにアクセスしても使えませんが、webサーバー上に置けば使えます。

IndexedDBを扱う処理は非同期です。
データベースへの接続やデータの挿入、取得などのリクエストが、成功したときにはonsuccess、失敗した時にはonerrorが呼び出されます。

データベース新規作成・接続

var dbName = 'sampleDB';

var openReq  = indexedDB.open(dbName);
// DB名を指定して接続。DBがなければ新規作成される。

  openReq.onupgradeneeded = function(event){
  //onupgradeneededは、DBのバージョン更新(DBの新規作成も含む)時のみ実行
    console.log('db upgrade');
  }
  openReq.onsuccess = function(event){
  //onupgradeneededの後に実行。更新がない場合はこれだけ実行
    console.log('db open success');
    var db = event.target.result;
    // 接続を解除する
    db.close();
  }
  openReq.onerror = function(event){
  // 接続に失敗
    console.log('db open error');
  }

db.close()しないままでも、indexedDB.open(dbName)はできる。
しかし、DBの更新や削除は、closeしてからでないとできない(onupgradeneeded, onsuccess, onerrorのどれも実行されない)。

データベース削除

var deleteReq = indexedDB.deleteDatabase(dbName);

  deleteReq.onsuccess = function(event){
    console.log('db delete success');
    // 存在しないDB名を指定してもこっちが実行される
  }

  deleteReq.onerror = function(){
    console.log('db delete error');
  }

オブジェクトストア作成

オブジェクトストアは、RDBでいうテーブル。

var storeName  = 'sampleStore';

var openReq = indexedDB.open(dbName, dbVersion);
// オブジェクトストアの作成・削除はDBの更新時しかできないので、バージョンを指定して更新

  openReq.onupgradeneeded = function(event){
    var db = event.target.result;
    db.createObjectStore(storeName, {keyPath : 'id'})
  }

オブジェクトストアの作成、削除はDBの更新時に実行されるonupgradeneededの中でしかできない。
DBの新規作成時以外でDBを更新するには、open()のときにDBの新しいバージョンを指定する。
現在のバージョンは、以下のように取得できる。

var dbVersion;
openReq.onsuccess = function(event){
  var db = event.target.result;
  dbVersion = db.version;
}

データ挿入

var data = {id : 'A1', name : 'test'};

var openReq = indexedDB.open(dbName);

openReq.onsuccess = function(event){
    var db = event.target.result;
    var trans = db.transaction(storeName, 'readwrite');
    var store = trans.objectStore(storeName);
    var putReq = store.put(data);

    putReq.onsuccess = function(){
      console.log('put data success');
    }

    trans.oncomplete = function(){
    // トランザクション完了時(putReq.onsuccessの後)に実行
      console.log('transaction complete');
    }

 }

putの他にaddもある。putはデータの挿入または更新で、addは挿入だけ。keyの値が重複したデータをaddしようとするとエラーになるが、putでは上書きする。

データ取得

var keyValue = 'A1';

var openReq = indexedDB.open(dbName);

  openReq.onsuccess = function(event){
    var db = event.target.result;
    var trans = db.transaction(storeName, 'readonly');
    var store = trans.objectStore(storeName);
    var getReq = store.get(keyValue);

    getReq.onsuccess = function(event){
      console.log(event.target.result); // {id : 'A1', name : 'test'}
    }
  }

そのままだと使いにくいと思われる方は、dexie.jsなどのラッパーも用意されているので試してみるといいかもしれません。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
167
Help us understand the problem. What are the problem?