IndexedDB触ってみた
ブラウザでもDB操作できます?
お試しも兼ねて備忘します
IndexedDBという名のデータベース
ブラウザに搭載されているDBなんだな、LocalStorageやSessionStorageなどのWeb Storage APIと同じ様にブラウザにデータを保存できる仕組み
特徴
- オンライン・オフライン
- 同一オリジンポリシー
- キーと値の組を格納 ("age": 44 みたな)
- トランザクションデータベースモデル
- 非同期
- SQLを使用しない(select * from user ← ☓)
早速試してみる
IndexedDBを操作するHTMLを作成してみました
こちらを使って試してみます
IndexedDB作成のHTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Indexeddb test</title>
</head>
<body>
<h1>IndexedDBのテスト</h1>
<div style="margin-bottom: 10px;"><button type="button" onclick="indexeddb_create();">IndexedDBの作成</button></div>
<div style="margin-bottom: 10px;"></div><button type="button" onclick="indexeddb_object_store_create();">IndexedDBにオブジェクトストアを作成</button></div>
<div style="margin-bottom: 10px;"></div><button type="button" onclick="indexeddb_insert_data();">IndexedDBにデータを作成</button></div>
<div style="margin-bottom: 10px;"></div><button type="button" onclick="indexeddb_select_data();">IndexedDBのデータを検索</button></div>
<div style="margin-bottom: 10px;"></div><button type="button" onclick="indexeddb_update_data();">IndexedDBのデータを更新</button></div>
<div style="margin-bottom: 10px;"></div><button type="button" onclick="indexeddb_select_data();">IndexedDBのデータを検索</button></div>
<div style="margin-bottom: 10px;"></div><button type="button" onclick="indexeddb_delete_data();">IndexedDBのデータを削除</button></div>
<div style="margin-bottom: 10px;"></div><button type="button" onclick="indexeddb_select_data();">IndexedDBのデータを検索</button></div>
<div style="margin-bottom: 10px;"></div><button type="button" onclick="indexeddb_object_store_delete();">IndexedDBのオブジェクトストアを削除</button></div>
<div style="margin-bottom: 10px;"></div><button type="button" onclick="indexeddb_delete();">IndexedDBの削除</button></div>
<hr>
<p>実行結果</p>
<p id="success"></p>
<hr>
<p style="color: #FF0000;">エラーが発生した場合</p>
<p id="error"></p>
<script>
const db_name = "MyTestDatabase";
const db_base_version = 1;
const db_object_store_create_version = 2;
const db_object_store_delete_version = 3;
const store_name = "customer";
const err = document.getElementById("error");
const success = document.getElementById("success");
const default_data = {id: '#12345#user_id', name: 'test taro'};
// indexeddb 作成
function indexeddb_create(){
const createRequest = window.indexedDB.open(db_name, db_base_version);
createRequest.onerror = (event) => {
err.innerHTML = event.target.error;
};
createRequest.onsuccess = (event) => {
db = event.target.result;
success.innerHTML = `${db_name}を作成しました。作成したバージョン = ${event.target.result.version}`;
// 接続を解除
db.close();
}
}
// object store 作成
function indexeddb_object_store_create(){
const openRequest = window.indexedDB.open(db_name, db_object_store_create_version);
openRequest.onupgradeneeded = (event) => {
const db = event.target.result;
// 顧客の情報を保存する objectStore を作成します
const objectStore = db.createObjectStore(store_name, { keyPath: "id" });
success.innerHTML = `${db_name}に${store_name}を作成しました。`;
// 接続を解除
db.close();
};
}
// insert データ
function indexeddb_insert_data(){
const openRequest = window.indexedDB.open(db_name);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onsuccess = (event) => {
const db = event.target.result;
const customerObjectStore = db.transaction(store_name, 'readwrite').objectStore(store_name);
customerObjectStore.add(default_data);
success.innerHTML = `${db_name}の${store_name}に${default_data.id}を追加しました。`;
// 接続を解除
db.close();
};
}
// update データ
function indexeddb_update_data(){
const openRequest = window.indexedDB.open(db_name);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onsuccess = (event) => {
default_data.name = 'テスト二郎';
const db = event.target.result;
const customerObjectStore = db.transaction(store_name, 'readwrite').objectStore(store_name);
customerObjectStore.put(default_data);
success.innerHTML = `${db_name}の${store_name}の${default_data.id}を更新しました。`;
// 接続を解除
db.close();
};
}
// delete データ
function indexeddb_delete_data(){
const openRequest = window.indexedDB.open(db_name);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onsuccess = (event) => {
const db = event.target.result;
const customerObjectStore = db.transaction(store_name, 'readwrite').objectStore(store_name);
customerObjectStore.delete(default_data.id);
success.innerHTML = `${db_name}の${store_name}の${default_data.id}を削除しました。`;
// 接続を解除
db.close();
};
}
// select
function indexeddb_select_data(){
const openRequest = window.indexedDB.open(db_name);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onsuccess = (event) => {
const db = event.target.result;
const customerObjectStore = db.transaction(store_name).objectStore(store_name);
const get_result = customerObjectStore.get(default_data.id);
get_result.onerror = (event) => {
err.innerHTML = event.target.error;
}
get_result.onsuccess = (event) => {
if (typeof get_result.result === 'undefined') {
success.innerHTML = `${db_name}の${store_name}からデータを取得できません`;
}
else {
success.innerHTML = `${db_name}の${store_name}からid:${get_result.result.id},name:${get_result.result.name}が見つかりました。`;
}
}
// 接続を解除
db.close();
};
}
// object store 削除
function indexeddb_object_store_delete(){
const openRequest = window.indexedDB.open(db_name, db_object_store_delete_version);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onupgradeneeded = (event) => {
const db = event.target.result;
//objectStoreを削除します
const objectStoreDelete = db.deleteObjectStore(store_name);
success.innerHTML = `${db_name}の${store_name}を削除しました。`;
};
}
// indexeddb 削除
function indexeddb_delete(){
const createRequest = window.indexedDB.deleteDatabase(db_name);
success.innerHTML = `${db_name}を削除しました。`;
}
</script>
</body>
</html>
※ブラウザの開発者モードを開いておいてください、私はChromeを使用しています
※サンプルソースを掲載していますが、不完全です。特にエラー処理関係を省いていますのでご承知願います
データベース作成
まずはデータベースを作成します
「IndexedDBの作成」ボタンを押すとデータベースが作成されます
ストレージ欄のIndexedDB欄にMyTestDatabaseが作成されました。
※データベースはMySQLやPosgre等のDatabaseとほぼ同じ概念と理解しています。
javascriptは以下となります
// indexeddb 作成
function indexeddb_create(){
const createRequest = window.indexedDB.open(db_name, db_base_version);
createRequest.onerror = (event) => {
err.innerHTML = event.target.error;
};
createRequest.onsuccess = (event) => {
db = event.target.result;
success.innerHTML = `${db_name}を作成しました。作成したバージョン = ${event.target.result.version}`;
// 接続を解除
db.close();
}
}
オブジェクトストアの作成
オブジェクトストアを作成します
「IndexedDBにオブジェクトストアを作成」ボタンを押すとオブジェクトストアが作成されます
MyTestDatabaseの配下にcustomerオブジェクトストアが作成されました。
※オブジェクトストアはMySQLやPosgre等のtableとほぼ同じ概念と理解しています。
javascriptは以下となります
// object store 作成
function indexeddb_object_store_create(){
const openRequest = window.indexedDB.open(db_name, db_object_store_create_version);
openRequest.onupgradeneeded = (event) => {
const db = event.target.result;
// 顧客の情報を保存する objectStore を作成します
const objectStore = db.createObjectStore(store_name, { keyPath: "id" });
success.innerHTML = `${db_name}に${store_name}を作成しました。`;
// 接続を解除
db.close();
};
}
データの登録
オブジェクトストアにデータを登録します
「IndexedDBにデータを作成」ボタンを押すとcustomerオブジェクトストアにデータが登録されます
※今回は固定のデータを用意しています。本来は入力値やAPI等で取得したデータを登録するはずです
customerオブジェクトストアが作成されました。
※データが最新でない可能性があります。と、開発者モードで警告されます。その際は開発者モード側の更新アイコンをクリックしてください
javascriptは以下となります
// insert データ
function indexeddb_insert_data(){
const openRequest = window.indexedDB.open(db_name);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onsuccess = (event) => {
const db = event.target.result;
const customerObjectStore = db.transaction(store_name, 'readwrite').objectStore(store_name);
customerObjectStore.add(default_data);
success.innerHTML = `${db_name}の${store_name}に${default_data.id}を追加しました。`;
// 接続を解除
db.close();
};
}
データの検索
オブジェクトストアのデータを検索します
「IndexedDBのデータを検索」ボタンを押すとcustomerオブジェクトストア登録されているデータを取得できます
javascriptは以下となります
// select
function indexeddb_select_data(){
const openRequest = window.indexedDB.open(db_name);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onsuccess = (event) => {
const db = event.target.result;
const customerObjectStore = db.transaction(store_name).objectStore(store_name);
const get_result = customerObjectStore.get(default_data.id);
get_result.onerror = (event) => {
err.innerHTML = event.target.error;
}
get_result.onsuccess = (event) => {
if (typeof get_result.result === 'undefined') {
success.innerHTML = `${db_name}の${store_name}からデータを取得できません`;
}
else {
success.innerHTML = `${db_name}の${store_name}からid:${get_result.result.id},name:${get_result.result.name}が見つかりました。`;
}
}
// 接続を解除
db.close();
};
}
データの更新
オブジェクトストアのデータを更新します
「IndexedDBのデータを更新」ボタンを押すとcustomerオブジェクトストアのデータが更新されます
ちゃんと更新されたか確認します。IndexedDBのデータを検索でデータを確認しましょう、nameが「test taro」→「テスト二郎」に変更されているはずです
javascriptは以下となります
// update データ
function indexeddb_update_data(){
const openRequest = window.indexedDB.open(db_name);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onsuccess = (event) => {
default_data.name = 'テスト二郎';
const db = event.target.result;
const customerObjectStore = db.transaction(store_name, 'readwrite').objectStore(store_name);
customerObjectStore.put(default_data);
success.innerHTML = `${db_name}の${store_name}の${default_data.id}を更新しました。`;
// 接続を解除
db.close();
};
}
データの削除
オブジェクトストアのデータを削除します
「IndexedDBのデータを削除」ボタンを押すとcustomerオブジェクトストアのデータが削除されます
ちゃんと削除されたか確認します。IndexedDBのデータを検索でデータを確認しましょう、データが削除されたので「MyTestDatabaseのcustomerからデータを取得できません」と表示されます
javascriptは以下となります
// delete データ
function indexeddb_delete_data(){
const openRequest = window.indexedDB.open(db_name);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onsuccess = (event) => {
const db = event.target.result;
const customerObjectStore = db.transaction(store_name, 'readwrite').objectStore(store_name);
customerObjectStore.delete(default_data.id);
success.innerHTML = `${db_name}の${store_name}の${default_data.id}を削除しました。`;
// 接続を解除
db.close();
};
}
オブジェクトストアの削除
オブジェクトストアを削除します
「IndexedDBのオブジェクトストアを削除」ボタンを押すとcustomerオブジェクトストアが削除されます
MyTestDatabase配下からcustomerオブジェクトストアが削除されました
javascriptは以下となります
// object store 削除
function indexeddb_object_store_delete(){
const openRequest = window.indexedDB.open(db_name, db_object_store_delete_version);
openRequest.onerror = (event) => {
console.log("error");
err.innerHTML = event.target.error;
};
openRequest.onupgradeneeded = (event) => {
const db = event.target.result;
//objectStoreを削除します
const objectStoreDelete = db.deleteObjectStore(store_name);
success.innerHTML = `${db_name}の${store_name}を削除しました。`;
};
}
データベースの削除
データベースを削除します
「IndexedDBの削除」ボタンを押すとデータベースが削除されます
MyTestDatabase配下からcustomerオブジェクトストアが削除されました
※ボタンを押した後、データベースは削除されるのですが、開発者モードから消えませんw
ブラウザ更新すると削除されていますのでご安心ください
javascriptは以下となります
// indexeddb 削除
function indexeddb_delete(){
const createRequest = window.indexedDB.deleteDatabase(db_name);
success.innerHTML = `${db_name}を削除しました。`;
}
振り返り
今回はIndexedDBを触ってみました
今までDBはバックエンドの専用ミドルだと思っていましたがフロントでもDBを立ち上げてデータ管理することができました
※ITって改めてすごい
ただ、使い方や勘どころ、セキュリティやベンチマーク等、まだまだ知らない事が多いです
今後少しずつでも触りながら勉強しています
※同一オリジンポリシーというものの、iframeでIndexedDBのページを読み込んでDBに登録されているデータとか読み込めちゃうのかな。。。
この記事が少しでも役立つ情報を提供できましたら幸いです。
読んでくださった皆様に心から感謝申し上げます
Discussion