[2021/06/03] JavaScript IndexedDB の使い方4(全データ取得) (No.270)
[2021/06/02] JavaScript IndexedDB の使い方3(データ取得) (No.269)
[2021/06/01] JavaScript IndexedDB の使い方2(データ追加) (No.268)
[2021/05/31] JavaScript IndexedDB の使い方1(データベースオープン) (No.267)
-
今回はカーソルを使って「オブジェクトストア」に登録された全てのデータを取得する方法について説明します。
カーソル処理を行う場合でも、データ追加処理と同様にデータベースの「トランザクション」を取得し、 「トランザクション」から「オブジェクトストア」オブジェクトを取得します。
その後で「オブジェクトストア」オブジェクトの openCursor メソッドでカーソルオープンのリクエストを行います。
openCursor メソッドの書式とイベント関数の定義は以下の様になります。 (尚 openCursor の引数のキー範囲指定は getAll と同様です。)// openCursorメソッド(objectStore:「オブジェクトストア」オブジェクト) var request = objectStore.openCursor( [query , [direction] ] ); request.onsuccess = function(event) { // 取得が成功した場合の関数宣言(event.target.result にカーソルデータが返る) var cursor = event.target.result; //取敢えず変数で受ける(cursor.value でデータが参照できる) }; request.onerror = function(event) { // 取得エラーの場合の関数宣言 }; <パラメータ> ・query:キー文字列または IDBKeyRange オブジェクトのクエリー指定 ・direction:カーソル移動の指定("next", "nextunique", "prev", "prevunique" を指定) "next" :キー昇順(デフォルト) "nextunique":キー昇順で重複キーは最初のデータを取得 "prev" :キー降順 "prevunique":キー降順で重複キーは最初のデータを取得 <戻り値> request :IDBRequest オブジェクト
openCursor メソッドが成功した時には event.target.result にカーソルオブジェクトが返ります。
このカーソルオブジェクトが「null」では無い場合、その中の「value」に実際のデータが入っています。
引き続き次のデータを取得したい場合には、カーソルオブジェクトの continue メソッドを行います。
次のデータが存在すれば、再度この onsuccess イベントが発生します。順次処理が進めば、指定の全てのデータの処理が行えます。
カーソルオブジェクトが「null」の場合は指定されたキー範囲(引数が無ければ全データが対象ですが)の全てのデータの取得が終わったことを示します。■簡単な openCursor メソッドとカーソルオブジェクトの continue メソッドの利用
<html> <head> <meta charset="utf-8"> <title>test IndexedDB - cursor - 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; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * 全データ取得処理 */ function getAllData() { //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //カーソル開始 var request = objectStore.openCursor(); //カーソルで対応するデータが存在した場合の処理 request.onsuccess = function(event) { var cursor = event.target.result; if(cursor) { console.log('データ:', cursor.value); //次のカーソルへ cursor.continue(); } else { //これ以上のデータは存在しない console.log('データ終了'); } }; //カーソル取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - cursor - 1</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <button id="buttonGet" onclick="getAllData()">全データ取得</button> <br /> </body> </html>
「DBオープン」ボタンをクリック後 「全データ取得」ボタンをクリックすると、 ブラウザの「ウエブ開発ツール」のコンソールに順次データレコードの内容が表示され、最後に「データ終了」が表示されるのが分かります(下図参照)。
上の例では openCursor メソッドの引数を指定していないので「オブジェクトストア」内の全データが返されます。
■openCursor メソッドにキー範囲とカーソル移動方向("next":昇順)の指定
getAll メソッドの時と同様に openCursor メソッドにキー範囲指定、およびカーソル移動方向を昇順指定を行い、結果を見てみます。
キー範囲は IDBKeyRange オブジェクトを使います。以下の例ではキーが '01' ~ '22' の範囲指定で、カーソル移動方向は 'next' を指定しています。 ('next' はデフォルトなので指定しなくても 'next' になります。)<html> <head> <meta charset="utf-8"> <title>test IndexedDB - cursor - 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; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * 全データ取得処理 */ function getAllData() { //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //キーの範囲指定オブジェクト var query = IDBKeyRange.bound('01', '22'); //キー範囲:'01'~'22' //カーソル開始 var request = objectStore.openCursor(query, 'next'); //キーの範囲指定、カーソル移動方向指定 //カーソルで対応するデータが存在した場合の処理 request.onsuccess = function(event) { var cursor = event.target.result; if(cursor) { console.log('データ:', cursor.value); //次のカーソルへ cursor.continue(); } else { //これ以上のデータは存在しない console.log('データ終了'); } }; //カーソル取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - cursor - 2</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <button id="buttonGet" onclick="getAllData()">全データ取得</button> <br /> </body> </html>
「DBオープン」ボタンをクリック後 「全データ取得」ボタンをクリックすると、 ブラウザの「ウエブ開発ツール」のコンソールににキーの昇順で順次データレコードの内容が表示され、最後に「データ終了」が表示されるのが分かります(下図参照)。
■openCursor メソッドにキー範囲とカーソル移動方向("prev":降順)の指定
getAll メソッドの時と同様に openCursor メソッドにキー範囲指定、およびカーソル移動方向を降順指定を行い、結果を見てみます。
キー範囲は IDBKeyRange オブジェクトを使います。以下の例ではキーが '01' ~ '22' の範囲指定で、カーソル移動方向は 'prev' を指定しています。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - cursor - 3</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; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * 全データ取得処理 */ function getAllData() { //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //キーの範囲指定オブジェクト var query = IDBKeyRange.bound('01', '22'); //キー範囲:'01'~'22' //カーソル開始 var request = objectStore.openCursor(query, 'prev'); //キーの範囲指定、カーソル移動方向指定 //カーソルで対応するデータが存在した場合の処理 request.onsuccess = function(event) { var cursor = event.target.result; if(cursor) { console.log('データ:', cursor.value); //次のカーソルへ cursor.continue(); } else { //これ以上のデータは存在しない console.log('データ終了'); } }; //カーソル取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - cursor - 3</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <button id="buttonGet" onclick="getAllData()">全データ取得</button> <br /> </body> </html>
「DBオープン」ボタンをクリック後 「全データ取得」ボタンをクリックすると、 ブラウザの「ウエブ開発ツール」のコンソールにキーの降順で順次データレコードの内容が表示され、最後に「データ終了」が表示されるのが分かります(下図参照)。
関連する記事
⇒JavaScript IndexedDB の使い方1(データベースオープン)
⇒JavaScript IndexedDB の使い方2(データ追加)
⇒JavaScript IndexedDB の使い方3(データ取得)
⇒JavaScript IndexedDB の使い方4(全データ取得)
⇒JavaScript IndexedDB の使い方5(カーソル処理)
⇒JavaScript IndexedDB の使い方6(データ削除)
PR -
今回は「オブジェクトストア」に登録された全てのデータを取得する方法について説明します。
全データを取得する場合でも、データ追加処理と同様にデータベースの「トランザクション」を取得し、 「トランザクション」から「オブジェクトストア」オブジェクトを取得します。
その後で「オブジェクトストア」オブジェクトの getAll メソッドで全データ取得のリクエストを行います。
getAll メソッドの書式とイベント関数の定義は以下の様になります。// getメソッド(objectStore:「オブジェクトストア」オブジェクト) var request = objectStore.getAll( [query , [count] ] ); request.onsuccess = function(event) { // 取得が成功した場合の関数宣言(event.target.result にデータの配列が返る) }; request.onerror = function(event) { // 取得エラーの場合の関数宣言 }; <パラメータ> ・query:キー文字列または IDBKeyRange オブジェクトのクエリー指定 ・count:返されるデータの数の指定 <戻り値> request :IDBRequest オブジェクト
getAll メソッドが成功した時には event.target.result にデータの配列が返るので、ここで行いたい処理を記述します。
尚、1件のみのデータ取得の get メソッドとは異なりデータの配列が返されるので注意が必要です。■簡単な getAll メソッドの利用
<html> <head> <meta charset="utf-8"> <title>test IndexedDB - allget - 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; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * 全データ取得処理 */ function getAllData() { //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //全データ取得 var request = objectStore.getAll(); //取得が成功した場合の関数宣言 request.onsuccess = function(event) { var result = event.target.result; // データ配列が返る!! console.log('データ:', result); }; //取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - allget - 1</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <button id="buttonGet" onclick="getAllData()">全データ取得</button> <br /> </body> </html>
「DBオープン」ボタンをクリック後 「全データ取得」ボタンをクリックすると、 ブラウザの「ウエブ開発ツール」のコンソールにArrayデータとしてレコードの内容が表示されるのが分かります(下図参照)。
上の例では getAll メソッドの引数を指定していないので「オブジェクトストア」内の全データが返されます。
■getAll メソッドにキー範囲とデータ件数の指定
そこで getAll メソッドにキー範囲とデータ件数の指定を行い、結果を見てみます。
キー範囲は IDBKeyRange オブジェクトを使います。以下の例ではキーが '01' ~ '22' の範囲で、データ件数は4件を指定しています。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - allget - 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; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * 全データ取得処理 */ function getAllData() { //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //キーの範囲指定オブジェクト var query = IDBKeyRange.bound('01', '22'); //キー範囲:'01'~'22' //データ取得 var request = objectStore.getAll(query, 4); //キーの範囲指定、データ数4件 //取得が成功した場合の関数宣言 request.onsuccess = function(event) { var result = event.target.result; // 4件のデータ配列が返る!! console.log('データ:', result); }; //取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - allget - 2</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <button id="buttonGet" onclick="getAllData()">全データ取得</button> <br /> </body> </html>
「DBオープン」ボタンをクリック後 「全データ取得」ボタンをクリックすると、 ブラウザの「ウエブ開発ツール」のコンソールにArrayデータとして4件のレコードの内容が表示されるのが分かります(下図参照)。
■キーが存在しないキー範囲指定
ここでキー範囲指定オブジェクトで以下の様に、キーが存在しない設定にすると、結果として0件のデータ配列が返されますので、注意が必要です。// [getAllData]関数のみ抜粋、その他は変更なし function getAllData() { //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //キーの範囲指定オブジェクト var query = IDBKeyRange.bound('05', '07'); //キー範囲:'05'~'07' //データ取得 var request = objectStore.getAll(query, 4); //キーの範囲指定、データ数4件 //取得が成功した場合の関数宣言 request.onsuccess = function(event) { var result = event.target.result; // 0件のデータ配列が返る!! console.log('データ:', result); }; //取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; }
「DBオープン」ボタンをクリック後 「全データ取得」ボタンをクリックすると、 ブラウザの「ウエブ開発ツール」のコンソールに0件のArrayデータとして表示されるのが分かります(下図参照)。
■キー範囲 IDBKeyRange オブジェクト
IDBKeyRange オブジェクトにはキー範囲を生成する bound , lowerBound , upperBound , only のメソッドがあります。 IDBKeyRange.bound は抽出するキー範囲を指定し、IDBKeyRange.lowerBound は指定キーより大きいか、以上のものを対象とし、 IDBKeyRange.upperBound は指定キーより小さいか、以下のものを対象とします。
また、IDBKeyRange.only は指定キーそのものが対象となります。
コード キー範囲 備考 IDBKeyRange.lowerBound(X) [全キー] ≧ (X)(X) 以上のキーが対象 IDBKeyRange.lowerBound(X, true) [全キー] > (X)(X) より大きいキーが対象 IDBKeyRange.upperBound(Y) [全キー] ≦ (Y)(Y) 以下のキーが対象 IDBKeyRange.upperBound(Y, true) [全キー] < (Y)(Y) より小さいキーが対象 IDBKeyRange.bound(X, Y) (X) ≦ [全キー]≦ (Y)(X) 以上かつ (Y) 以下のキーが対象 IDBKeyRange.bound(X, Y, true, true) (X) < [全キー]< (Y)(X) より大きくかつ (Y) より小さいキーが対象 IDBKeyRange.bound(X, Y, true, false) (X) < [全キー]≦ (Y)(X) より大きくかつ (Y) 以下のキーが対象 IDBKeyRange.bound(X, Y, false, true) (X) ≦ [全キー]< (Y)(X) 以上かつ (Y) より小さいキーが対象 IDBKeyRange.only(Z) [キー] = (Z)キーが (Z) のものが対象
■その他注意点
今回の getAll メソッドは Internet Explorer では実装されていません。
Edge には実装されていますが Internet Explorer で全データの取得を行う場合は、カーソル処理で行う必要があります。 (2022年には IE のサポートを終了するというアナウンスが Microsoft からあったので、これからは IE をそこまで気にしなくても良くなりそうですが)
なお、カーソル処理については次の記事で紹介したいと思います。
関連する記事
⇒JavaScript IndexedDB の使い方1(データベースオープン)
⇒JavaScript IndexedDB の使い方2(データ追加)
⇒JavaScript IndexedDB の使い方3(データ取得)
⇒JavaScript IndexedDB の使い方4(全データ取得)
⇒JavaScript IndexedDB の使い方5(カーソル処理)
⇒JavaScript IndexedDB の使い方6(データ削除)
-
今回は「オブジェクトストア」に登録されたデータを取得する方法について説明します。
データを取得する場合でも、データ追加処理と同様にデータベースの「トランザクション」を取得し、 「トランザクション」から「オブジェクトストア」オブジェクトを取得します。
その後で「オブジェクトストア」オブジェクトの get メソッドでデータ取得のリクエストを行います。
get メソッドの書式とイベント関数の定義は以下の様になります。// getメソッド(objectStore:「オブジェクトストア」オブジェクト) var request = objectStore.get(id); request.onsuccess = function(event) { // 取得が成功した場合の関数宣言(event.target.result にデータが返る) }; request.onerror = function(event) { // 取得エラーの場合の関数宣言 }; <パラメータ> ・id:キー文字列またはキーの範囲指定 <戻り値> request :IDBRequest オブジェクト
get メソッドが成功した時には event.target.result にデータが返るので、ここで行いたい処理を記述します。
以下に簡単な get メソッドの利用ソースを示します。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - add - 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; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * データ取得処理 */ function getData() { //キー値 var id = $("#id").val(); //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //一件取得 var request = objectStore.get(id); //取得が成功した場合の関数宣言 request.onsuccess = function(event) { var result = event.target.result; console.log('データ:', result); }; //取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - add - 2</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> id:<input type="text" name="id" id="id" value="" /> <button id="buttonGet" onclick="getData()">データ取得</button> <br /> </body> </html>
「DBオープン」ボタンをクリック後 ID のテキストボックスに「01」を入力し「データ取得」ボタンをクリックすると、 ブラウザの「ウエブ開発ツール」のコンソールにデータが表示されるのが分かります(下図参照)。
そこで ID のテキストボックスをクリアし「データ取得」ボタンをクリックすると、コンソールに undefined と表示されます。 また「111」などのキーが存在しないで「データ取得」ボタンをクリックしても同様に undefined と表示されます。
データが undefined の判定処理を onsuccess イベントに追加して undefined では無い場合にデータ処理を行う様に変更します。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - get - 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; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * データ取得処理 */ function getData() { //キー値 var id = $("#id").val(); //トランザクション var transaction = db.transaction(objStoreName, 'readonly'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //一件取得 var request = objectStore.get(id); //取得が成功した場合の関数宣言 request.onsuccess = function(event) { var result = event.target.result; if (result !== undefined) { console.log('データ:', result); } else { console.log('データが見つからない!!'); } }; //取得エラーの場合の関数宣言 request.onerror = function(event) { console.log('取得失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - get - 2</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> id:<input type="text" name="id" id="id" value="" /> <button id="buttonGet" onclick="getData()">データ取得</button> <br /> </body> </html>
関連する記事
⇒JavaScript IndexedDB の使い方1(データベースオープン)
⇒JavaScript IndexedDB の使い方2(データ追加)
⇒JavaScript IndexedDB の使い方3(データ取得)
⇒JavaScript IndexedDB の使い方4(全データ取得)
⇒JavaScript IndexedDB の使い方5(カーソル処理)
⇒JavaScript IndexedDB の使い方6(データ削除)
-
前回は IndexedDB の「データベース」および「オブジェクトストア」の作成を説明しましたが、 データベースの入れ物ができれば次に行うのはデータの登録ではないでしょうか。
今回は「オブジェクトストア」にデータを追加する方法について説明します。
データベースに対してデータの追加を行う場合には「トランザクション」と言うものを使用します。
この「トランザクション」ですがデータベースの「オブジェクトストア」に対して何かの処理を行う時には、開始しなければならない様です。
トランザクションは readonly、readwrite、versionchange の3個のモードがありますが、 versionchange はデータベースのオブジェクトストアやインデックスを作成または削除する場合に使いますが、 今回はデータの操作なので readwrite を指定します。 なお readonly はデータの取得(参照)のみの場合に利用します。
トランザクション開始の書式とイベント関数の定義は以下の様になります。
// トランザクション開始(IDBDatabase.transaction()) var transaction = db.transaction(storeNames, [ mode , [ options ] ] ); // (db : データベースオープンの成功時に退避されたデータベースインスタンス) <パラメータ> ・storeNames:オブジェクトストア名を文字列配列、または文字列(単一の場合)で指定します。 ['store1', 'store2', 'store3', ...] の様に配列か 'store1' の1個の指定でもOK var transaction = db.transaction(db.objectStoreNames); ⇒ データベースの全てのオブジェクトストア指定 ・mode :"readonly", "readwrite", "versionchange" ・options :"default", "strict", "relaxed" (通常は指定無しでOKです) <戻り値> transaction :IDBTransaction オブジェクト このオブジェクトの正常時とエラー時イベントハンドラにユーザ関数を定義して各処理を行う。 // イベントの関数定義 transaction.oncomplete = function(event) { // トランザクションが正常に終了した場合に呼ばれる関数宣言 }; transaction.onerror = function(event){ // トランザクションでエラーが発生した場合に呼ばれる関数宣言 };
このトランザクションから「オブジェクトストア」オブジェクトを取得し、データ処理を行います。// トランザクション開始(IDBDatabase.transaction()) var transaction = db.transaction(storeNames, [ mode , [ options ] ] ); // 「オブジェクトストア」オブジェクトを取得 var objectStore = transaction.objectStore(storeName); <パラメータ> ・storeName:オブジェクトストア名を文字列で指定します。 <戻り値> objectStore :IDBObjectStore オブジェクト
■IDBObjectStoreのメソッドメソッド 処理 説明 add データ追加 新規のデータをオブジェクトストアに追加する。
戻り値 IDBRequest の onsuccess , oneerror イベントで処理が必要であれば宣言する。clear 全データ削除 オブジェクトストアの全データを削除する。
戻り値 IDBRequest の onsuccess , oneerror イベントで処理が必要であれば宣言する。count データ件数取得 件数検索にキーまたは、キーの範囲指定により件数取得する。
キー(範囲)の指定が無ければ、オブジェクトストアの全件数を取得する。
戻り値 IDBRequest の onsuccess イベントで件数取得する。delete データ指定削除 キーまたは、キーの範囲指定によりデータ削除する。
戻り値 IDBRequest の onsuccess , oneerror イベントで処理が必要であれば宣言する。get データ取得 キーの指定によりデータ取得する。
戻り値 IDBRequest の onsuccess イベントでデータ取得する。getAll 指定全データ取得 件数検索にキーまたは、キーの範囲指定によりデータ取得する。
データ取得はカーソル処理を使って行う。openCursor カーソルオープン 件数検索にキーまたは、キーの範囲指定によりカーソルオープンする。
戻り値 IDBRequest の onsuccess イベントでカーソル(event.target.result)が返される。
カーソルの continue() メソッドで次のカーソルへ処理が移る。
IDBObjectStoreのメソッドは上記の他にもありますが、それは「MDN Web Doc」を参照して頂くとして、 このブログではこれらを順に説明していきます。
まず最初にデータの追加「add」メソッドについて説明します。
■データ追加処理
IDBObjectStore の add メソッドを使ったデータ追加の例を以下に示します。
データベースオープン処理は、前回の記事とほぼ同じですが、 データベース名、オブジェクトストア名は先頭の方で宣言する様にしています。
IDBObjectStore の add メソッドの引数にはデータのオブジェクトを渡しますが、 オブジェクトストアの生成で指定した keyPath の要素名は必須です。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - add - 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; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //DBが存在しない場合、またはバージョン引数よりも小さい場合の作成処理 request.onupgradeneeded = function(event) { //データベースインスタンス保存 db = event.target.result; db.onerror = function(event) { //エラー処理 console.log('DBの作成に失敗しました。'); }; //オブジェクトストア名の確認 if (!db.objectStoreNames.contains(objStoreName)) { //オブジェクトストアが無い場合 var objStoreKey = { keyPath: 'id' }; //キー設定 //var objStoreKey = { autoIncrement: true }; //autoIncrementのみ指定 //オブジェクトストア生成 var obj = db.createObjectStore(objStoreName, objStoreKey); console.log("オブジェクトストア生成"); } }; //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * データ追加処理 */ function addData() { //トランザクション var transaction = db.transaction(objStoreName, 'readwrite'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //オブジェクトストアに追加のリクエストします。 var data = { id: '01' , //キーデータ data1: 'abcde' , //文字列データ data2: 123 , //数値データ data3: { data3_1: '001', data3_2: 1000 } //オブジェクトデータ }; var request = objectStore.add(data); //追加正常の場合の関数宣言 request.onsuccess = function(event) { console.log('保存成功'); }; //追加エラーの場合の関数宣言 request.onerror = function(event) { console.log('保存失敗。event:', event); }; } </script> </head> <body> <h2>test IndexedDB - add - 1</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <button id="buttonAdd" onclick="addData()">データ追加</button> <br /> </body> </html>
「DBオープン」ボタンをクリック後「データ追加」ボタンをクリックすると、 データベース「TestDB」の中にオブジェクトストア「Test1」が生成され、その中にデータが1件存在することが分かります。再度「データ追加」ボタンをクリックするとエラーが発生し、データが追加されません。
オブジェクトストアの生成で指定した keyPath の指定があるので id は重複キーを許可されません。
但し、オブジェクトストア生成の前でコメント行としている autoIncrementのみ指定 に変更すれば、 データ項目の中の主キーの指定が無くなります。
そこで、HTMLファイルを変更し再度ブラウザに読込みを行います。この後でブラウザの「ウエブ開発ツール」上でデータベースを削除を行います。
再度「DBオープン」ボタンをクリック後「データ追加」ボタンを複数回クリックすると、同じデータがオブジェクトストアに登録されます。
この場合、オブジェクトストアのなかでは「Key」という項目でデータが付加されその値が順次増加(autoIncrement)していきます。
そこで少しソースを変更し、複数のデータを登録できる様に変更します。 「addData」関数をサブ関数として与えられるデータが配列でも処理できる様にします。<html> <head> <meta charset="utf-8"> <title>test IndexedDB - add - 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; // データベース名 var dbName = "TestDB"; // オブジェクトストア名 var objStoreName = "Test1"; /** * DB接続処理 */ function openDB() { // データベースオープン:[名称:TestDB] var request = indexedDB.open(dbName); //DBが存在しない場合、またはバージョン引数よりも小さい場合の作成処理 request.onupgradeneeded = function(event) { //データベースインスタンス保存 db = event.target.result; db.onerror = function(event) { //エラー処理 console.log('DBの作成に失敗しました。'); }; //オブジェクトストア名の確認 if (!db.objectStoreNames.contains(objStoreName)) { //オブジェクトストアが無い場合 var objStoreKey = { keyPath: 'id' }; //キー設定 //オブジェクトストア生成 var obj = db.createObjectStore(objStoreName, objStoreKey); console.log("オブジェクトストア生成"); } }; //オープンが正常の場合の関数宣言 request.onsuccess = function(event) { //データベースインスタンス保存 db = event.target.result; console.log("DBオープンOK"); }; //エラーの場合の関数宣言 request.onerror = function(event){ console.log("DBオープンエラー"); }; } /** * データ追加処理SUB */ function _addData(data) { //トランザクション var transaction = db.transaction(objStoreName, 'readwrite'); //オブジェクトストアにアクセスします。 var objectStore = transaction.objectStore(objStoreName); //単独データを1件の配列データにする var arrData = new Array(); if (Array.isArray(data) == false) { arrData[0] = data; } else { arrData = data; } for (var i in arrData) { //オブジェクトストアに追加のリクエストします。 var request = objectStore.add(arrData[i]); //追加正常の場合の関数宣言 request.onsuccess = function(event) { console.log('保存成功'); }; //追加エラーの場合の関数宣言 request.onerror = function(event) { console.log('保存失敗。event:', event); }; } } /** * データ追加処理 */ function addData() { //配列データの例 var data = [ { id: '01' , data1: 'abcde' , data2: 123 , data3: { data3_1: '001', data3_2: 1000 } }, { id: '02' , data1: 'a0002' , data2: 200 , data3: { data3_1: '002', data3_2: 2000 } }, { id: '03' , data1: 'a0003' , data2: 300 , data3: { data3_1: '003', data3_2: 3000 } }, { id: '11' , data1: '11111' , data2: 111 , data3: { data3_1: '101', data3_2: 1111 } }, { id: '22' , data1: '2222' }, { id: '33' , data2: 222 } ]; //単独データの例 //var data = { id: '11' , data1: '11111' , data2: 111 , data3: { data3_1: '101', data3_2: 1111 } }; _addData(data); } </script> </head> <body> <h2>test IndexedDB - add - 2</h2> <button id="buttonOpen" onclick="openDB()">DBオープン</button> <button id="buttonAdd" onclick="addData()">データ追加</button> <br /> </body> </html>
このソースではオブジェクトストアの生成で keyPath の指定があるので id は重複キーを許可されませんので、 データの中の「id」はユニークになる様に設定します。
そこで、HTMLファイルを変更し 配列データを登録する様にして再度ブラウザに読込み、ブラウザの「ウエブ開発ツール」上でデータベース「TestDB」のオブジェクトストア「Test1」の全データの削除を行います。 その後「DBオープン」ボタンさらに「データ追加」ボタンをクリックします。
そうしますと、以下の図の様にオブジェクトストア「Test1」に6件のデータが登録されます。
ここで注意点ですが、データの「id」は必須なのですが、その他のデータは指定されたままの状態で登録されています。 登録されるデータの制約は keyPath で指定された要素名が存在すればよく、その他は Javascript のオブジェクトであればOKな様です。関連する記事
⇒JavaScript IndexedDB の使い方1(データベースオープン)
⇒JavaScript IndexedDB の使い方2(データ追加)
⇒JavaScript IndexedDB の使い方3(データ取得)
⇒JavaScript IndexedDB の使い方4(全データ取得)
⇒JavaScript IndexedDB の使い方5(カーソル処理)
⇒JavaScript IndexedDB の使い方6(データ削除)
-
今回はブラウザ内にで用意されているローカルなデータベース機能を提供する 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(データ削除)