Indexed DB 는 사용자의 브라우저에 데이터를 영구적으로 저장하는 방법 중 하나이다. localStorage 보다 많은 용량의 데이터를 저장할 수 있고, JS 에서 사용하는 객체 형식 그대로 저장할 수 있다.
가장 먼저 데이터베이스 open 요청을 해야한다.
open 메소드의 첫번재 매개변수엔 데이터베이스의 이름, 두번째 매개변수엔 데이터베이스의 버전이 들어간다. 이때 버전은 정수로만 표현돼야 한다.
if (!window.indexedDB) { // 지원여부 확인하기
alert(`your browser doesn't support indexed DB`);
}
const dbName = 'SuyeonDB';
const version = 1;
const request = window.indexedDB.open(dbName, version); // 데이터 베이스 열기 요청
db 삭제는 deleteDatabase 메서드를 통해 삭제한다.
const request = window.indexedDB.deleteDatabase(dbName);
1. 새로운 데이터 베이스를 만들거나, 2. 기존의 데이터베이스 버전 보다 높은 데이터베이스를 부를 때 onupgradeneeded
이벤트가 트리거 된다.
해당 이벤트 처리를 해주는 코드 안에서 새로운 객체 저장소를 생성해준다.
request.onupgradeneeded = function(event) {
const db = event.target.result;
const objectStore = db.createObjectStore('friend', { // 저장소 이름 = friend
keyPath: 'id',
autoIncrement: true
});
}
onupgradeneeded
이벤트가 끝나면 DB 열기 요청의 onsuccess
가 트리거 된다.
request.onError = function(event) {
// 에러에 대한 처리
}
request.onupgradeneeded = function(event) {
// 스토리지 생성
}
request.onsuccess = function(event) {
console.log('suyeon DB 확인!');
}
DB 생성 모습과 onsuccess 콘솔을 확인할 수 있다.
❓ 트랜잭션이 뭔가요
트랙잭션은 데이터베이스의 상태(데이터)를 변화시키기 위한 작업을 의미한다. 즉 데이터베이스의 데이터의 수정, 삭제, 삽입 등을 위해선 트랜잭션을 생성해주어야 한다는 의미이다.
transaction 메소드를 사용해 transaction을 열 수 있다.
request.onsuccess = function(event) {
const db = event.target.result;
const transaction = db.transaction(storeName, mode);
transaction.oncomplete = (e) => {} // 성공처리
transaction.onerror = (e) => {} // 에러처리
}
이때 여러개의 저장소에 접근하고 싶은 경우 배열 요소로 store 를 집어넣으면 된다.
const transaction = db.transaction(['store1', 'store2']);
스토어에 저장하기 위해 스토어를 다시 불러온다.
request.onsuccess = function(event) {
// 생략
const transaction = db.transaction(storeName, mode);
const objectStore = transaction.objectStore('friend');
}
친구 정보를 위한 객체를 따로 만들어 저장소에 저장해준다.
const friends = [
{name: '김정호', team:'front'},
{name: '김유진', team:'front'},
{name: '송인재', team:'front'},
{name: '우지호', team:'front'},
{name: '조수연', team:'front'},
];
request.onsuccess = function(event) {
// 생략
const transaction = db.transaction(storeName, mode);
const objectStore = transaction.objectStore('friend');
friends.forEach((e, i) => {
const request = objectStore.add(e);
request.onsuccess = (e) => { // ... } // 성공에 대한 처리
})
}
예쁘게 들어간 우리 팀원들의 이름…
데이터는 get 함수와 키값을 통해 가져올 수 있다.
const key = 5;
const request = objectStore.get(key); // IDBRequest 객체 반환
console.log(request.result); // name: 조수연 team: front
갑자기 내가 백엔드로 가고 싶어진다면 어떻게 해야할까. get 으로 값을 가져온 다음 put 함수로 수정해주면 된다.
const key = 5;
const request = objectStore.get(key);
request.onsuccess = (e) => {
objectStore.put({name: 조수연, 'team': back'});
}
마찬가지로 key 값을 통해 삭제하면 된다.
const key = 5;
const request = objectStore.delete(key); // 조수연 삭제
get 으로 key 값을 가져오려면 key 값을 우리가 알고 있어야 한다.
key 값을 모르는 상태에서 전체 데이터를 조회하고 싶을 땐 cursor 를 사용하면 된다.
objectStore.openCursor().onsuccess = (e) => {
const cursor = e.target.result;
if (cursor) {
console.log(`key: ${cursor.key} name: ${cursor.value.name}`);
cursor.continue(); // continue 를 사용해 연속 조회
}
}
만약 이름이 조수연
인 사람의 데이터를 찾고 싶을 때, id 를 통해 검색하려면 한번씩 순회를 하며 이름을 검색해야할 것이다. 이런 방식은 비효율적이므로 프로퍼티에 index 를 부여하여 검색할 수 있다.
index 를 사용하려면 onupgradeneeded
에서 index 설정을 해줘야한다.
// onupgradeneeded
const indexReq = store.createIndex('name', 'name'); // index 추가
// onsuccess
index.get('조수연').onsuccess = (e) => { // name 프로퍼티 중 조수연이란 이름을 가진
console.log(e.target.result);
}
onupgradeneeded 는 데이터베이스가 처음 만들어지거나 버전이 업그레이드 될 때 실행되므로 db를 처음부터 새로 생성했다.
request.onupgradeneeded = (e) => {
const db = e.target.result;
const store = db.createObjectStore('friend', {
keyPath: 'id',
autoIncrement: true
});
const indexReq = store.createIndex('name', 'name'); // index 추가
}
request.onsuccess = (e) => {
const db = e.target.result;
const transaction = db.transaction('friend', 'readwrite');
const store = transaction.objectStore('friend');
const index = store.index('name');
index.get('조수연').onsuccess = (e) => {
console.log(e.target.result);
}
}
이름을 통해서도 데이터가 잘 출력되는 걸 확인할 수 있다!