前回は 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(データ削除)