今回はブラウザ内にで用意されているローカルなデータベース機能を提供する IndexedDB の使い方について説明します。
IndexedDB はローカルなブラウザに、キーインデックスを付加したひとかたまりのJavaScript オブジェクトを保存できます。
このデータベースはブラウザのプログラムを終了してもローカルなフォルダに保存されているので、 再度同じWEBページを開いた時にデータを再利用ができます。
尚、この IndexedDB は MySQL の様なリレーショナルデータベースとは全く異なり、以下の点で注意が必要です。
- テーブルの概念は無く代わりに「オブジェクトストア」と呼ばれるものがあります。
- データ処理は SQL 文で処理せず「オブジェクトストア」用の追加、更新、削除、取得などのメソッド(API)を使用します。
- データ取得は「オブジェクトストア」のカーソルをオープンし順次処理します。
- IndexedDBのAPIは、ほぼ非同期処理で処理結果に対応する関数を渡します。(XMLHttpRequestの様な)
先ずは IndexedDB を使うにあたって以下のものを最初に宣言します。
以前は Google Chrome と Firefox ではベンダープレフィックスを付けた名称だったため、今回も取敢えず宣言します。
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
■IndexedDB オープンメソッド
通常のデータベースと同様に IndexedDB のデータベースを使用時には最初にオープン処理が必要です。
オープン処理は open 関数を使いますが書式は以下の通りです。 尚、オープン処理と同時に各種のイベント関数を宣言し、オープン処理結果を待ち受けてやります。
// オープン処理
var request = indexedDB.open( dbName [ , verNo ] );
<パラメータ>
・dbName:データベース名を文字列で指定します。
・verNo :バージョンNOを数値で指定します。
<戻り値>
request :IDBOpenDBRequest オブジェクト
このオブジェクトのイベントハンドラにユーザ関数を定義して各処理を行う。
// イベントの関数定義
request.onupgradeneeded = function(event) {
// 初回オープン時または、バージョンNOが登録済みより大きい場合に呼ばれる関数宣言
};
request.onsuccess = function(event) {
// 接続が正常に終了した場合に呼ばれる関数宣言
};
request.onerror = function(event){
// オープン時にエラーが発生した場合に呼ばれる関数宣言
};
■簡単な IndexedDB オープン処理
以下に IndexedDB のオープン処理の簡単な例を示します。
データベース名は「TestDB」としてオープンのリクエストを行い onsuccess , onerror イベントの処理を宣言しています。
onsuccess のイベントの中の request.result は IDBDatabase のインスタンスですので、グローバルな変数に保存します。 このインスタンスを使って各種のデータ処理が行える様になります。
<html>
<head>
<meta charset="utf-8">
<title>test IndexedDB - 1</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
// ブラウザ対応宣言
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
// データベース(IDBDatabase)インスタンス
var db;
/**
* DB接続処理
*/
function openDB() {
// データベースオープン:[名称:TestDB]
var request = indexedDB.open("TestDB");
//オープンが正常の場合の関数宣言
request.onsuccess = function(event) {
//データベースインスタンス保存
db = event.target.result;
alert("DBオープンOK");
};
//エラーの場合の関数宣言
request.onerror = function(event){
alert("DBオープンエラー");
};
}
</script>
</head>
<body>
<h2>test IndexedDB - 1</h2>
<button id="buttonOpen" onclick="openDB()">DBオープン</button>
<br />
</body>
</html>
下図はこのHTMLファイルを FireFox で呼出した直後で、「ツール」⇒「ブラウザツール」⇒「ウエブ開発ツール」を開いたところです。
「ストレージ」 の項目を見ると 「Indexed DB」 がありますので、 その中の 「http://localhost」 をさらにみるとまだ何も存在しないことが分かります。
ブラウザのサイトの「DBオープン」をクリックして再度 「ストレージ」 の項目の 「Indexed DB」 の 「http://localhost」 をみると 「TestDB」 が作成されていることが分かります。
(これを見る場合には一旦「ウエブ開発ツール」を閉じてから再度開く必要があります)
「TestDB」 は作成されましたが Indexed DB のテーブルの様な「オブジェクトストア」が存在しないので、これを作成してみます。
上記の HTML ファイルのソースに onupgradeneeded イベントを追加し、その中で「オブジェクトストア」を生成する様に変更します。 ファイルは以下の様になります。
■オブジェクトストアの生成を伴う IndexedDB オープン処理
<html>
<head>
<meta charset="utf-8">
<title>test IndexedDB - 1 - 2</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
// ブラウザ対応宣言
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
// データベース(IDBDatabase)インスタンス
var db;
/**
* DB接続処理
*/
function openDB() {
// データベースオープン:[名称:TestDB]
var request = indexedDB.open("TestDB");
//DBが存在しない場合、またはバージョン引数よりも小さい場合の作成処理
request.onupgradeneeded = function(event) {
//データベースインスタンス保存
var db = event.target.result;
db.onerror = function(event) { //エラー処理
alert("DBの作成に失敗しました。");
};
var objStoreName = "Test1"; //オブジェクトストア名
if (!db.objectStoreNames.contains(objStoreName)) {
//オブジェクトストアが無い場合
var objStoreKey = { keyPath: 'id' }; //キー設定
//オブジェクトストア生成
var obj = db.createObjectStore(objStoreName, objStoreKey);
}
};
//オープンが正常の場合の関数宣言
request.onsuccess = function(event) {
//データベースインスタンス保存
db = event.target.result;
alert("DBオープンOK");
};
//エラーの場合の関数宣言
request.onerror = function(event){
alert("DBオープンエラー");
};
}
</script>
</head>
<body>
<h2>test IndexedDB - 1 - 2</h2>
<button id="buttonOpen" onclick="openDB()">DBオープン</button>
<br />
</body>
</html>
最初の処理で作成された 「TestDB」 を削除するために、「ツール」⇒「ブラウザツール」⇒「ウエブ開発ツール」を開きます。
「ストレージ」 の項目を見ると 「Indexed DB」 があるのでその中の 「http://localhost」 の 「TestDB」 で右クリックをして「"TestDB(Default)"を削除」メニューを実行します。
さらに、上記の「オブジェクトストア」の生成を含んだHTMLファイルを読み込み「DBオープン」をクリックして再度データベースの生成を行います。
「ストレージ」 の項目の 「Indexed DB」 の 「http://localhost」 をみると 「TestDB」 が作成され、 その中に 「Test1」 の「オブジェクトストア」が存在することが分かります。
(これを見る場合には一旦「ウエブ開発ツール」を閉じてから再度開く必要があります)
尚、ここでデータベース「IDBDatabase」の createObjectStore メソッドに付いて説明します。
// 書式
var obj = IDBDatabase.createObjectStore(name [, options] );
<パラメータ>
・name :オブジェクトストア名を文字列で指定します。
・options :オプションパラメーターとなる属性を持つオプションオブジェクト。
これは次のプロパティを持つ。
//optionsプロパティ
・keyPath :オブジェクトストアの主キー(in-line keys)として使用されるデータ内の項目名。
空や特定されていない場合 Key Path なしで生成されて out-of-line keys が使用される。
・autoIncrement:trueだった場合、オブジェクトストアはkey generatorを持つ。既定値はfalse。
<戻り値>
obj :IDBObjectStoreオブジェクト
キーパス (keyPath) と キージェネレータ(autoIncrement) の指定方法の違いによる説明は以下の通りです。
キーパス(keyPath) | キージェネレータ(autoIncrement) | 説明 |
指定なし |
指定なし |
オブジェクトストアは、数値や文字列といったプリミティブ値を含む、どのような種類の値でも保持できます。
新たな値の追加を望むたびに、個別のキー引数を供給しなければなりません。 |
指定あり |
指定なし |
ブジェクトストアは、JavaScript オブジェクトのみ保持できます。
オブジェクトはキーパスと同じ名称のプロパティを持たなければなりません。 |
指定なし |
指定あり |
このオブジェクトストアは、どのような種類の値でも保持できます。
キーは自動的に生成されます。また、特定のキーを使用したい場合は個別のキー引数を供給できます。 |
指定あり |
指定あり |
このオブジェクトストアは、JavaScript オブジェクトのみ保持できます。
通常はキーが生成されて、オブジェクトでキーパスと同じ名称を持つプロパティに、生成されたキーの値を保存します。
ただしそのようなプロパティがすでに存在している場合は、生成された新たなキーではなく、そのプロパティの値をキーとして使用します。 |
(MDN Web Doc より)
さて、ここまでで「データベース」と「ブジェクトストア」の生成が終わりましたので、 別の記事でデータ処理に付いて説明を行いたいと思います。
keyPath と autoIncrement の指定ですが keyPath を指定あり autoIncrement を指定なしの指定で今後は進めていきます。 (主キーを文字列データで与えてデータ登録を行う感じです。)
関連する記事
⇒
JavaScript IndexedDB の使い方1(データベースオープン)
⇒
JavaScript IndexedDB の使い方2(データ追加)
⇒
JavaScript IndexedDB の使い方3(データ取得)
⇒
JavaScript IndexedDB の使い方4(全データ取得)
⇒
JavaScript IndexedDB の使い方5(カーソル処理)
⇒
JavaScript IndexedDB の使い方6(データ削除)