iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

IndexedDBの基本を学ぶ

はじめに

こんにちは!株式会社iimonでフロントエンドエンジニアをしている「みよちゃん」です! 本記事は株式会社iimonアドベントカレンダー15日目です! 弊社では不動産仲介業者向けのサービスを開発しています。 私が所属しているチームでは、chrome拡張機能を開発しており、IndexeDBを使用する機会が多くあります。 今回は普段使用するIndexedDBについて調べたことを以下にまとめていきたいと思います!

IndexedDB

1. IndexedDBとは

IndexedDBとはブラウザに実装されているデータベースの機能です。ブラウザ内で処理を完結させることができるので、通信が発生せずオフラインの状態でも使用することができます。データベースはRDB(Relational Database)ではなくキーバリューストアです。

2. ブラウザが持つほかのデータ管理機能との違い

ブラウザのデータ管理機能といえば他にも「Cookie」「SessionStorage」「LocalStorage」などがあげられます。これらと比較したIndexedDBの特徴は   * 手動で削除するまで残り続ける * ブラウザによるデータの制限なし(ディスクの空き容量により制限あり) * データにはクライアントのみアクセス可能 * 任意のデータ形式を使用できる これらの特徴からIndexedDBは複雑なデータを大量に、かつ長期間保存するのに向いていると言えそうです。

IndexedDBの使い方

1. データベースを開く

const name = 'DB_NAME'; // データベースの名前(文字列)
const version = 1; // バージョン(デフォルトは1)
let openRequest = indexedDB.open(name, version);

openRequestのイベントには以下の3つがあります。 * success:データベースの準備ができたことを示します。 * error :データベースを開くのに失敗したことを示します。 * upgradeneeded:DBのバージョンが最新でない場合にトリガーされます。

2. オブジェクトストア作成

IndexedDBのオブジェクトストアとは、ほかのデータベースでテーブルコレクションと呼ばれるものです。DBは複数のオブジェクトストアを持つことができます。

const storeName = 'user'

openRequest.onupgradeneeded = (e) => {
    const db = e.target.result;
    db.createObjectStore(storeName,{keyPath:'id'}
}

オブジェクトストアの作成、削除はonupgradeneededの中でしか実行できないので注意が必要です。

3. トランザクション

トランザクションの流れは基本的に以下の4ステップです。 1. トランザクションを作成する 1. 操作するために1に対してオブジェクトストアを取得する 1. 2に対してリクエストを実行する 1. リクエストの成功/失敗に応じて必要な処理を実行する

a. アイテムの追加

今回はuserというオブジェクトストアにiimonkunというnameをもつオブジェクトを追加してみましょう!

// 1.トランザクションを作成する
const transaction = db.transaction(storeName, 'readwrite');
// 2. トランザクションを操作するためのオブジェクトストアを取得する
const objectStore = transaction.objectStore(storeName);
const iimonkun = {
    id: 2,
    name:'iimonkun',
    age: 4,
}
// 3. リクエストの実行とresponseに応じたハンドリング
const request = store.add(iimonkun);

request.onsuccess = () => {
    console.log('created new user');
}

request.onerror = () => {
    console.log('error', request.error);
}

今回はaddを使用してアイテムの追加を行いましたが、putを使用することもできます。 addが同じkeyを持つ値が既に存在する場合にリクエストが失敗するのに対し、putは同じkeyを持つ値が存在する場合に値が置き換えられるという違いがあります。 目的に応じた使い方ができると良いですね!

b. データの取得

ここでは先ほどオブジェクトストアに追加したiimonkunnameを使用して取り出してみましょう!

const transaction = db.transaction('user', 'readonly');
const store = transaction.objectStore('user');

const index = store.index('name');
const request = index.get('iimonkun');

request.onsuccess = (e) => {
    const data = e.target.result;
    console.log('検索結果', data);


};

それではコンソールを確認してみましょう!
indexDB1.png

成功です!!うまく取り出せていますね!! IndexedDBでは以下のように検索する方法もあります。

getAll()

const request = objectStore.getAll()
request.onsuccess = (e) =>{
    // resultには全てのデータが配列で渡される
    const result = e.target.result;
}

getAllでは全てのデータを配列で取得することができます。

openCursor()

const transaction = db.transaction('user', 'readonly');
sotre = transaction.objectStore('user')

cursorRequest = sotre.openCursor();

cursorRequest.onsuccess = (e) => {
    // この中で反復処理が行われる
    const cursor = event.target.result;
    if(cursor.age <= 4){
        console.log(`${cursor.name} is under 4 years old .`)
    }
    cursor.continue();
}

cursorを使用するとストア内のデータに対して反復処理を行うことができます。複数の条件でデータを検索したいときなどに便利かもしれませんね!

c. アイテムの削除

それでは最後にアイテムの削除を行ってみましょう。今回はopenCursorでデータを削除してみます!

const transaction = db.transaction('data', 'readwrite');
const store = transaction.objectStore('data');

const deleteRequest = store.openCursor()
 deleteRequest.onsuccess = (e) => {
  const cursor = e.target.result;
  if(!cursor) return;

  if(cursor.value.name === 'iimonKun'){
    cursor.delete();
    console.log('success to delete')
  }
  cursor.continue();
}

cursorのname値がiimonkunだった時にデータを削除するような処理になています。 それではデータが削除できているか確認してみましょう。

blog-console.png

イメージ通り削除されていますね! これは削除処理に限った話ではありませんが、cursorでループを回す場合cursor.continueで次のループに移りますが、ループ終了の判定を自身で実装しなければならないので注意が必要です。

おわりに

今回改めてIndexedDBに関して調べたところ、あまり意識していなかった他データ管理機能との違いなど、新しい気づきがありました。今回学習した内容を元にIndexedDBを使用するべきタイミングや、適切なデータの扱い方を意識して業務を行えればと思います!

最後までご覧いただきありがとうございます。 弊社ではエンジニアを募集しております! この記事を見て気になった方、是非一度カジュアルにお話ししましょう! ご応募心よりお待ちしております!!! Wantedly / Green

次回のアドベントカレンダー記事担当は我らがCTO「もりご」さんです! 先日ダーツがかなりの腕前であることが発覚した「もりご」さん、きっとみなさんの心に刺さる記事を書いて下さることでしょう!! 今から楽しみですね!

参考記事

IndexedDB IndexedDB API