인스타그램 클론코딩 과정 중 indexedDB를 처음 다루고있다. 생활코딩 indexedDB강의를 바탕으로indexedDB의 기본개념과 사용방법을 정리해보고자 한다.
브라우저에 정보를 저장하는 기술은 대표적으로 Cookie, LocalStorage, indexedDB가 있다.
이 중 indexedDB의 상대적인 특징은 다음과 같다.
Database를 만들고 Object Store를 만들고 Object를 저장하고 읽고 수정하고 삭제할 수 있는 구조이다.
<script>
const dbReq = indexedDB.open('opentutorials',1);
let db;
dbReq.addEventListener('success', function(event){
db = event.target.result;
});
dbReq.addEventListener('error', function(event){
const error = event.target.error;
console.log('error', error.name);
});
</script>
indexedDB에 open함수를 호출하여 데이터베이스의 이름과 버전을 입력한다.
const dbReq = indexedDB.open('databaseName', version)
즉시 데이터베이스가 만들어지는 것이 아니라 IDBOpenDBRequest를 전달받는다.
dbrequest는 쉽게 말해 대기번호 같은 개념이다.
dbReq.addEventListener('success', function(event){});
addEventListener를 이용하여 success한다면 (데이터베이스가 생성되거나 이미 존재한다면) callback함수를 실행시킨다.
event.target은 dbReq변수를 가리킨다.
dbreq가 갖고있는 result를 통해 생성된 데이터베이스에 접근할 수 레퍼런스를 얻게된다.
이 레퍼런스는 애플리케이션에서 전역적으로 사용되어야 하기 때문에 바깥에서 let을 이용해 db라는 이름으로 변수를 선언하였다.
dbReq.addEventListener('error', function(event){});
에러가 발생했을 때의 예외상황을 처리하는 것도 중요하다.
에러 이벤트를 설치하여 에러를 핸들링 할 수 있다.
이는 open에서 뿐만 아니라 아래 진행되는 add, get, put등과 같은 작업들에서도 에러 이벤트를 설치해서 사용하게된다.
<script>
dbReq.addEventListener('upgradeneeded', function(event){
db = event.target.result;
let oldVersion = event.oldVersion;
if(oldVersion < 1){
db.createObjectStore('topics', {keyPath:'id', autoIncrement:true});
}
});
</script>
브라우저의 마지막 버전과 소스코드의 최신버전이 일치하지 않을 때 upgradeneeded 이벤트가 실행된다.
처음 데이터베이스를 만들었을 때도 실행된다.
upgradeneeded는 버전이 업데이트 될 때만 실행되기 때문에 object store를 만들기에도 최적이다.
createObjectStore함수를 이용하여 object store 생성한다.
db.createObjectStore('topics', {keyPath:'id', autoIncrement:true});
<input type="button" value="add" onclick="
let store = db.transaction('topics', 'readwrite').objectStore('topics');
let addReq = store.add({
title:prompt('title?'),
body:prompt('body?')
});
addReq.addEventListener('success', function(event){
console.log(event);
});
">
let store = db.transaction('topics', 'readwrite').objectStore('topics');
transaction함수를 사용하여 object store를 가져온다.
첫번째 파라미터에는 객체를 추가할 object store 이름,
두번째 파라미터에는 transaction mode 를 입력한다.
transaction mode의 종류
구체적으로 코드를 뜯어보자
아래 코드를 통해 'topics'object store에 대한 레퍼런스를 얻는다.
let store = db.transaction('topics', 'readwrite').objectStore('topics');
object store에 연결되는 레퍼런스에 add함수를 호출한다.
함수의 파라미터로 들어가는 객체가 object store에 저장된다.
let addReq = store.add({
title:prompt('title?'),
body:prompt('body?')
});
success 이벤트를 설치하면 즉각적으로 객체가 추가되는 것이 아니라,
아래와 같이 모드(readwrite) 쓰기작업이 끝났을 때 함수가 실행된다.
쓰기작업이 끝나고 실행될 후속 작업 코드를 입력하면 된다.
마찬가지로 에러 이벤트도 설치할 수 있다.
addReq.addEventListener('success', function(event){
console.log(event);
});
<input type="button" value="get" onclick="
let id = Number(prompt('?id'));
let store = db.transaction('topics', 'readonly').objectStore('topics');
let getReq = store.get(id);
getReq.addEventListener('success', function(event){
console.log(event.target.result);
});
">
let id = Number(prompt('?id'));
읽어오는 객체의 id 값을 가져온다
이 경우에 사용자가 입력한 정보는 문자열이기 때문에 숫자로 컨버팅한다.
let store = db.transaction('topics', 'readonly').objectStore('topics');
객체 추가하기와 동일하게 transection함수를 이용하여 object store를 가져온다.
여기서는 읽기 전용으로 transaction mode를 readonly로 설정한다.
let getReq = store.get(id);
get api를 이용하여 식별자를 입력하고 객체를 가져오는 변수를 설정한다.
getReq.addEventListener('success', function(event){});
이벤트를 설치하여 성공했을 때 후속 작업 코드를 입력한다.
마찬가지로 에러 이벤트도 설치할 수 있다.
let store = db.transaction('topics', 'readonly').objectStore('topics');
transection함수를 이용하여 object store를 가져온다.
읽기 전용으로 transaction mode를 readonly로 설정한다.
let getAllReq = store.getAll();
getAll api를 호출하면 모든 데이터를 가져온다.
getReq.addEventListener('success', function(event){});
이벤트를 설치하여 성공했을 때 후속 작업 코드를 입력한다.
마찬가지로 에러 이벤트도 설치할 수 있다.
let store = db.transaction('topics', 'readwrite').objectStore('topics');
transection함수를 이용하여 object store를 가져온다.
수정해야하므로 transaction mode를 readwrite로 설정한다.
let putReq = store.put({
id:Number(prompt('id?')),
title:prompt('title?'),
body:prompt('body?')
});
put api를 사용하여 수정할 내용을 입력한다. 식별자(id값)을 명시해줘야한다.
getReq.addEventListener('success', function(event){});
이벤트를 설치하여 성공했을 때 후속 작업 코드를 입력한다.
마찬가지로 에러 이벤트도 설치할 수 있다.
let store = db.transaction('topics', 'readwrite').objectStore('topics');
transection함수를 이용하여 object store를 가져온다.
transaction mode를 readwrite로 설정한다.
let deleteReq = store.delete(Number(prompt('id?')));
deleteReq.addEventListener('success', function(event){});
delete api를 사용하여 삭제할 객체의 식별자(id값)을 입력한다.
getReq.addEventListener('success', function(event){});
이벤트를 설치하여 성공했을 때 후속 작업 코드를 입력한다.
마찬가지로 에러 이벤트도 설치할 수 있다.
엘리스에서 사용한 코드와 생활코딩에서 정리한 코드가 같은 용도임에도 많이 다르다.
그래도 주요 키워드는 모두 동일하기 때문에 indexedDB 기본적인 동작 원리를 이해할 수 있는 시간이었다. indexedDB를 사용할 일이 많이 없다고하지만 내가 애용하는 YoutubeMusic에서 오프라인 저장 기능이 indexedDB를 사용한다고 하니 신기하기도 하고. 빨리 다른 database도 공부하여 이해도를 기르고싶다.