The sky is the limit

ハイブリッドアプリ開発、PWAなど効率の良いiOSアプリ、Androidアプリ開発の情報を共有したい。アプリ開発は楽しい。【PWA、AngularJS、Monaca、Cordova、OnsenUI】

【html5】indexedDBの使い方

【html5】indexedDBの使い方

f:id:duo-taro100:20160218004611p:plain

今回は、次回のハイブリッドアプリ開発で使用を考えているindexedDBを学びます。

indexedDBの実装内容

うまく表示されない場合はリロードをお願いします。

See the Pen indexedDB by duotaro (@duotaro100) on CodePen.

indexedDBの確認方法【Gromeoogle Ch】

macOSのchrome場合は以下のように確認できます。
データがない場合は特に何も表示されません。

①ページで右クリック
②「検証」を選択 → デベロッパー・ツールが表示される
③デベロッパー・ツールの上部にある「Application」タブ?を選択
④Storageの項目にあるIndexedDBを確認

DBやテーブルの追加時には、IndexedDBを右クリックして「Refresh IndexedDB」を選択して下さい。

【indexedDB】DBの新規作成

新規作成は以下の通りです。
もしすでにDBが存在している場合はそのDBに接続します。

indexedDB.open('データベース名');

テスト

/**
 * 指定したDBに接続します。
 * 存在しない場合は新規作成します。
 * データベース作成のみ。
 * @param {string} dbName
 */
var createDB = function(dbName){
	// DBに接続(新規作成)
	var dbRequest = indexedDB.open(dbName);

	// 新規作成時とか更新時
	dbRequest.onupgradeneeded = function(event){
	    alert('DBが新たに作成されました。DB名 : ' + dbName);
	}
	// 接続が上手く行った時
    dbRequest.onsuccess = function(event){
	    alert('DBに接続されました。DB名 : ' + dbName)
	    var db = event.target.result;
	    // 生成されたtransactionが全て完了したら接続が閉じられる。(ここではtransactionを作成していない) 
	    db.close();
	}
	// エラー時
	dbRequest.onerror = function(event){
	    console.log('DBの接続に失敗しました。');
	}
}

【indexedDB】テーブルの追加

indexedDBでは、既にDBが存在する状態で、テーブルの追加などを実施する場合はDBのバージョンを更新する必要があります。
更新する方法は以下の通りです。
新規作成時にはバージョンが「1」なので、初回の更新時にはそれよりも大きな数値を指定すれば大丈夫です。

indexedDB.open('データベース名', '更新バージョン');


テーブルの追加方法は以下の通りです。

db.createObjectStore('追加するテーブル名', {keyPath : 'データを取得するためのキー'})

keyPathはデータを取得するためのキーとなる値を決める項目です。
例えば、userテーブルに以下のようなデータがあったとします。

{
	id : '00001',
	userName : 'user1',
	birthday : '20101120'
}

kyePathを「id」としていた場合は、「00001」をキーとして上記データの取得が可能です。
基本的にはデータの中で一意となるものをkeyPathに設定します。

/**
 * 指定したDBに接続します。
 * テーブルを追加します
 * @param {string} dbName
 * @param {string} dbVer
 * @param {string} tableName
 * @param {string} key
 */
var updateDB = function(dbName, dbVer, tableName, key){

	// DBに接続
	var dbRequest = indexedDB.open(dbName, dbVer);
	var version;

	dbRequest.onupgradeneeded = function(event){
	    var db = event.target.result;
	    // 新規作成テーブルがあれば作成する
	    // テーブル作成用のメソッドとするなら、このif文はいらないです。
	    if(tableName){
	    	// DBにテーブルを追加します。
	    	db.createObjectStore(tableName, {keyPath : key})
	    	alert('DBにテーブルを追加しました。テーブル名 : ' + tableName + ' / keyPath : ' + key);
	    }
	}
    dbRequest.onsuccess = function(event){
	    alert('DBに接続されました。')
	    var db = event.target.result;
	    db.close();
	}
	dbRequest.onerror = function(event){
	    console.log('DBの接続に失敗しました。');
	}
}

【indexedDB】データの追加

データの追加方法は以下の通りです。
データを追加するには、transactionを開始する必要があります。
その際に、テーブル名に対してどのような操作が可能かを指定します。
ここでは、読み書きを可能とする「readwrite」を宣言しています。
また、存在しないテーブルに対してtransactionの作成を行うと以下のエラーが生じます。

Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.

// transactionを開始
var trans = db.transaction('データを追加するテーブル名', 'readwrite');

// オブジェクトストアを取得
var store = trans.objectStore('データを追加するテーブル名');

// データを追加
var putRequest = store.put('追加するデータ');

データの追加には「put」と「add」がありますが、以下のような違いがあります。
・put → 上書き可能。
・add → 上書き不可能。上書きしようとするとエラーが生じます。

/**
 * 指定したDBに接続して、データをindertします。
 * DBが存在しない場合は新規作成します。
 * テーブルが存在しない場合も新規作成します。
 * @param {string} dbName
 * @param {string} tabelName
 * @param {string} key
 * @param {object} data
 */
var insertDB = function(dbName, tableName, key, data){

	// DBに接続
	var dbRequest = indexedDB.open(dbName);
	var version;

    dbRequest.onsuccess = function(event){
	    alert('DBに接続されました。')
	    var db = event.target.result;

	    // テーブルが読み書き可能であることを宣言している。
	    var trans = db.transaction(tableName, 'readwrite');
	    var store = trans.objectStore(tableName);
	    // テーブルにデータを追加・更新
	    var putRequest = store.put(data);

	    db.close();
	}
	dbRequest.onerror = function(event){
	    console.log('DBの接続に失敗しました。');
	}
}

データの取得

データの取得方法は以下の通りです。
テーブル作成時に指定したkeyPathの値を使ってデータを取得します。

var transaction = db.transaction(tableName);
var store = transaction.objectStore(tableName);
// データを取得
// ここのkeyに指定するのは、テーブル作成時に指定したkeyPathの値
var result = store.get(key);

// 取得が成功したら呼ばれる
result.onsuccess = function(event) {
  // eventからデータを取得
  var data = event.target.result
  alert('id:' + data.id + ' / name:' + data.userName)
};
/**
 * 指定したDBに接続して、データを取得します。
 * 指定したキーに紐づくデータを取得します。
 * @param {string} dbName
 * @param {string} tabelName
 * @param {string} key
 */
var getValue = function(dbName, tableName, key){
	// DBに接続
	var dbRequest = indexedDB.open(dbName, dbVersion);
	var version;

    dbRequest.onsuccess = function(event){
	    alert('DBに接続されました。')
	    var db = event.target.result;

	    // userテーブルが読み書き可能であることを宣言している。
	    var transaction = db.transaction(tableName);
	    var store = transaction.objectStore(tableName);
	    // データを取得
	    var result = store.get(key);
	    result.onsuccess = function(event) {
	      var data = event.target.result
	      // {id : 'id', userName : 'name'} というデータを想定
		  alert('取得したユーザーのid:' + data.id + ' / ユーザー名:' + data.userName)
		};

	    db.close();
	}
	dbRequest.onerror = function(event){
	    console.log('DBの接続に失敗しました。');
	}
}