Progressive Web Apps(PWA)コアテクノロジ-Indexed DB

9130 ワード

使用中はhtml、css、jsなどのファイル情報をcacheキャッシュするのが一般的ですが、いくつかの特殊なデータはデータベースのサポートを借りる必要があります.ここではIndexedDBの使用をお勧めします.
IndexedDBは大規模なnoSQLストレージシステムです.これにより、ユーザーのブラウザに任意のコンテンツを格納できます.通常の検索、取得、および保存操作に加えて、IndexedDBはトランザクションをサポートします.
ブラウザがIndexedDBをサポートしているかどうかを確認します
if (!('indexedDB' in window)) {
  console.log('This browser doesn\'t support IndexedDB');
  return;
}

データベースの作成IndexedDBを使用すると、複数のデータベースを作成できますが、原則としてアプリケーションごとに1つのデータベースを作成する必要があります.
name:データベース名、version:バージョン番号、upgradeCallback:コールバックメソッド
idb.open(name, version, upgradeCallback)

IndexedDBのオブジェクトストレージ
主に、データベースがコールバックで返されるインスタンスを作成してcreateObjectStoreメソッドを呼び出すことで、オブジェクトストレージを作成します.
 if (!('indexedDB' in window)) {
    console.log('This browser doesn\'t support IndexedDB');
    return;
  }

  var dbPromise = idb.open('test-db2', 1, function(upgradeDb) {
    console.log('making a new object store');
    if (!upgradeDb.objectStoreNames.contains('firstOS')) {
      upgradeDb.createObjectStore('firstOS');
    }
  });
  • プライマリ・キーを定義し、自己増加を設定keyPathを使用してプライマリ・キーを定義し、autoIncrementを使用してプライマリ・キー自己増加を設定します.
  •   var dbPromise = idb.open('test-db3', 1, function(upgradeDb) {
    
        if (!upgradeDb.objectStoreNames.contains('logs')) {
          upgradeDb.createObjectStore('logs', {keyPath: 'id', autoIncrement: true});
        }
      });
    
  • インデックス作成インデックスを定義し、オブジェクトストレージインスタンスでcreateIndexメソッドを呼び出す:
  • objectStore.createIndex('indexName','property',options);
    

    このメソッドはインデックスオブジェクトを作成して返します.createIndexは、新しいインデックスの名前を最初のパラメータとし、2番目のパラメータはインデックスするデータの属性を指します.最後のパラメータでは、インデックスがどのように動作するかを決定する2つのオプションを定義できます.uniqueとmultiEntryです.uniqueがtrueに設定されている場合、インデックスは単一のキーの重複値を許可しません.インデックス属性が配列である場合、multiEntryはcreateIndexの動作を決定します.trueに設定すると、createIndexは各配列要素のインデックスにエントリを追加します.そうでなければ、配列を含むエントリが追加されます.
      var dbPromise = idb.open('test-db4', 1, function(upgradeDb) {
        if (!upgradeDb.objectStoreNames.contains('people')) {
          var peopleOS = upgradeDb.createObjectStore('people', {keyPath: 'email'});
          peopleOS.createIndex('gender', 'gender', {unique: false});
          peopleOS.createIndex('ssn', 'ssn', {unique: true});
        }
      });
    

    注:インデックスは、リファレンス・オブジェクト・ライブラリにデータを書き込むたびに更新されます.インデックスが多いほどIndexedDBのワークロードが大きくなることを意味します.
    IndexedDBのオペレーションデータIndexedDBのすべてのデータオペレーションは、1つのトランザクションで実行されます.各操作には、次のような形式があります.
    1.データベース・オブジェクトを取得する2.データベース上でトランザクション3を開く.トランザクションでオブジェクトストレージ4を開く.オブジェクトストレージでのアクションの実行
    データを書き込むデータを作成するには、オブジェクトストレージでaddメソッドを呼び出し、追加するデータを入力します.Addには、作成時に単一のオブジェクトにプライマリ・キーを定義できるオプションの2番目のパラメータがありますが、createObjectStoreでキー・パスを指定しない場合にのみ使用できます.
    someObjectStore.add(data, optionalKey);
    dbPromise.then(function(db) {
      var tx = db.transaction('store', 'readwrite');//      
      var store = tx.objectStore('store');
      var item = {
        name: 'sandwich',
        price: 4.99,
        description: 'A very tasty sandwich',
        created: new Date().getTime()
      };
      store.add(item);
      return tx.complete;
    }).then(function() {
      console.log('added item to the store os!');
    });
    

    データを読み込むデータを読み込むには、オブジェクトストレージのgetメソッドを呼び出します.getメソッドは、ストレージから取得するオブジェクトのプライマリ・キーを使用します.
    someObjectStore.get(primaryKey);
    dbPromise.then(function(db) {
      var tx = db.transaction('store', 'readonly');//      
      var store = tx.objectStore('store');
      return store.get('sandwich');//         undefined
    }).then(function(val) {
      console.dir(val);
    });
    

    データを更新データを更新するには、オブジェクトストレージでputメソッドを呼び出します.putメソッドはaddメソッドとよく似ており、addの代わりにオブジェクトストレージにデータを作成するために使用できます.addのようにputのデータとオプションのプライマリ・キー:
    someObjectStore.put(data, optionalKey);
    dbPromise.then(function(db) {
      var tx = db.transaction('store', 'readwrite');
      var store = tx.objectStore('store');
      var item = {
        name: 'sandwich',
        price: 99.99,
        description: 'A very tasty, but quite expensive, sandwich',
        created: new Date().getTime()
      };
      store.put(item);
      return tx.complete;
    }).then(function() {
      console.log('item updated!');
    });
    

    データを削除するには、データを削除し、格納オブジェクトでdeleteメソッドを呼び出します.
    someObjectStore.delete(primaryKey);
    dbPromise.then(function(db) {
      var tx = db.transaction('store', 'readwrite');
      var store = tx.objectStore('store');
      store.delete(key);
      return tx.complete;
    }).then(function() {
      console.log('Item deleted');
    });
    

    すべてのデータを取得
    また、getAllメソッドを使用するか、カーソルを使用してオブジェクトストレージまたはインデックスからすべてのデータ(またはサブセット)を取得することもできます.
  • getallメソッドを使用して、指定したキーまたはキー範囲に一致するオブジェクトストレージ内のすべてのオブジェクトを返します.

  • someObjectStore.getAll(optionalConstraint);
    dbPromise.then(function(db) {
      var tx = db.transaction('store', 'readonly');
      var store = tx.objectStore('store');
      return store.getAll();
    }).then(function(items) {
      console.log('Items by name:', items);
    });
    
  • カーソルを使用する別のデータを取得する方法は、カーソルを使用することです.カーソルは、オブジェクトストレージまたはインデックス内の各オブジェクトを1つずつ選択し、データを選択するときに操作を実行します.

  • someObjectStore.openCursor(optionalKeyRange, optionalDirection);
    dbPromise.then(function(db) {
      var tx = db.transaction('store', 'readonly');
      var store = tx.objectStore('store');
      return store.openCursor();
    }).then(function logItems(cursor) {
      if (!cursor) {
        return;
      }
      console.log('Cursored at:', cursor.key);
      for (var field in cursor.value) {
        console.log(cursor.value[field]);
      }
      return cursor.continue().then(logItems);
    }).then(function() {
      console.log('Done cursoring');
    });
    

    このメソッドはpromiseを返し、カーソルオブジェクトでオブジェクトストレージ内の最初のオブジェクトを表し、オブジェクトがない場合はundefinedを返します.オブジェクトストレージの次のオブジェクトに移動するにはcursorを呼び出します.continue.
    まず、データベース・オブジェクトを取得し、トランザクションを作成し、オブジェクト・ストレージを開きます.オブジェクトストレージ上でopenCursorメソッドを呼び出し、カーソルオブジェクトを渡す.thenのコールバック関数.今回はコールバック関数を「logItems」と名付けたので、関数内部から呼び出してループすることができます.if(!cursor){return;}もしそうならOpenCursor()が返すpromiseはundefined,またはcursorとして解析される.continue()が返すpromiseはundefinedとして解析される(より多くのオブジェクトがないことを示す).
    カーソルオブジェクトには、プロジェクトのプライマリ・キーを表すキー・プロパティが含まれます.また、データを表す値プロパティも含まれます.logItemsが終わるとcursorに戻ります.continue().then(logItems). cursor.continueメソッドは、store内の次のstoreを表すカーソルオブジェクトとして解析されるpromiseを返し、より多くのオブジェクトがない場合はundefinedを返します.この結果は伝えられた.thenのコールバック関数ではlogItemsをこの関数として選択し,関数がループする.したがって、logItemsはオブジェクトが保持されないまで自分を呼び出し続けます.
    インデックスによる範囲内のデータの取得
    すべてのデータを異なる方法で得ることができますが、特定の属性に基づくデータのサブセットしか必要ありませんか?インデックスを使用できます.インデックスでは、プライマリ・キー以外のプロパティからオブジェクト・ストレージのデータを取得します.任意のプロパティにインデックスを作成し、そのプロパティに範囲を指定し、getallメソッドまたはカーソルを使用して範囲内のデータを取得できます.
    IDBKeyRangeオブジェクトを使用して範囲を定義します.このオブジェクトには、upperBound、lowerBound、bound(これは両方を意味する)、onlyの4つの方法があります.upperBoundメソッドとlowerBoundメソッドは、範囲の上限と下限を指定します.IDBKeyRange.lowerBound(indexKey); IDBKeyRange.upperBound(indexKey); IDBKeyRange.bound(lowerIndexKey, upperIndexKey); IDBKeyRange.only(indexKey);
    function searchItems(lower, upper) {
      if (lower === '' && upper === '') {return;}
    
      var range;
      if (lower !== '' && upper !== '') {
        range = IDBKeyRange.bound(lower, upper);
      } else if (lower === '') {
        range = IDBKeyRange.upperBound(upper);
      } else {
        range = IDBKeyRange.lowerBound(lower);
      }
    
      dbPromise.then(function(db) {
        var tx = db.transaction(['store'], 'readonly');
        var store = tx.objectStore('store');
        var index = store.index('price');//    
        return index.openCursor(range);
      }).then(function showRange(cursor) {
        if (!cursor) {return;}
        console.log('Cursored at:', cursor.key);
        for (var field in cursor.value) {
          console.log(cursor.value[field]);
        }
        return cursor.continue().then(showRange);
      }).then(function() {
        console.log('Done cursoring');
      });
    }
    

    データベース・バージョン番号の使用
    var dbPromise = idb.open('test-db7', 3, function(upgradeDb) {
      switch (upgradeDb.oldVersion) {
        case 0:
          upgradeDb.createObjectStore('store', {keyPath: 'name'});
        case 1:
          var storeOS = upgradeDb.transaction.objectStore('store');
          storeOS.createIndex('price', 'price');
        case 2:
          var storeOS = upgradeDb.transaction.objectStore('store');
          storeOS.createIndex('description', 'description');
      }
    });
    

    ブラウザにデータベースがない場合、oldVersionは0になり、case:0から順に0、1、2を実行し、プライマリ・キーがnameのストレージ・オブジェクトを作成し、そのオブジェクトにpriceのインデックスとdescriptionのインデックスを作成します.
    ブラウザにデータベースが存在し、priceというインデックスが作成されている場合、oldVersionが2の場合、0,1はスキップされ、descriptionというインデックスが直接作成されます.
    注意:ここのcaseにはbreakはありません.
    参照リンク:https://developers.google.com/web/ilt/pwa/working-with-indexeddb#getting_all_the_data