[HTML/Javascript] indexedDB에 대해 알아보자!

???? indexedDB는 무엇이며, 어떻게 사용하는 걸까? 이번 시간에는 indexedDB정의와 사용법에 대해 알아보았다! (마지막에는 vue에서는 indexedDB를 어떻게 사용하는지 링크도 공유해두었다 참고해보자!)

1. indexedDB?

1) indexedDB는 무엇일까?

(1) indexedDB의 정의

  • 우리가 데이터를 저장할 때, 클라이언트 스토리지(브라우저 제공 db)를 이용할 수 있다.
  • 클라이언트 스토리지에는 localStoragecookiesindexedDB가 존재한다.

❓ 그런데 localStorage 대신 indexedDB를 쓰는 이유가 있을까?

  • localStoage의 경우
    : 적은 양의 데이터를 저장할 때 유용하다.
    : 동기적으로 작동하며, 오직 문자열 타입의 키&값만을 사용할 수 있다.
    : 그렇기 때문에 JSON.stringifyJSON.parse와 같은 함수가 꼭 필요하다.
  • indexedDB의 경우
    : 그에 반해 indexedDB는 많은 양의 구조화된 데이터를 저장할 때 유용하다.
    : localStoage와 달리, JS가 인식할 수 있는 자료형과 객체를 저장할 수 있다.
    : 키, 값 형태로 데이터가 저장되며 문자열 타입이 아니어도 된다.
    : 특이한 점은 비동기적으로 작동한다는 점이다.

 

(2) indexedDB 패턴

❓ indexedDB는 localStoage보다 절차가 조금 복잡한데, 기본 패턴은 아래와 같다.

  • 데이터베이스 열기
  • 데이터베이스에 객체 저장소(Object store) 생성하기
  • 트랜젝션(Transaction) 시작하기 (데이터 읽기, 쓰기 제거 등 데이터베이스 작업 요청)
  • 이벤트 리스너를 사용하여 요청이 완료될때까지 기다리기
  • 요청 결과를 가지고 어떤 동작하기


 



 

2. indexedDB 사용해보기

1) 데이터베이스 열기

(1) open 함수로 dataBase 열기

  • 브라우저에서 여러 개의 데이터베이스를 만들 수 있다.
  • 데이터베이스는 버전 정보를 가지고 있으며, 여러 개의 ObjectStore(객체 저장소)를 가질 수 있다.
  • 단, 데이터베이스 수정시 버전을 수정해줘야 한다!
  • open 명령어를 사용해 데이터베이스를 열도록 요청할 수 있다.
window.indexedDB.open(db_name, version)

 

(2) 예시 코드

  • 아래 코드는 데이터베이스를 여는 과정이다.
// 1. indexedDB 객체 가져오기
const idxedDB = window.indexedDB;

// 2. 브라우저에서 지원하는지 체크하기
if (!idxedDB) window.alert('해당 브라우저에서는 indexedDB를 지원하지 않습니다.')
else {
  let db;
  const request = idxedDB.open('SampleDB');   // 3. SampleDB(db) 열기
  request.onerror =(e)=> alert('failed');
  request.onsuccess =(e)=> db = request.result;

}

 

 


 

2) database에 ObjectStore 추가하기

(1) ObjectStore 생성하기

  • ObjectStore는 데이터를 담는 공간이다.
  • 여러 개의 레코드(key-value)를 가진다.
  • ObjectStore의 이름은 고유해야 한다.
  • 각 객체에 유일성을 부여하기 위해 keyPath를 정의해야 한다.
  • createObjectStore를 사용해 특정 DB에 ObjectStore를 추가할 수 있다.
  • 단, createObjectStore는 onupgradeneeded 이벤트와 함께 써야 한다.
IDBRequest.createObjectStore('store_name', {keyPath: 'id'})

 

(2) onupgradeneeded?

  • onupgradeneeded는 아래와 같은 상황에 발생하는 이벤트이다.
  이벤트 발생 상황
  새로운 데이터 베이스 만들 때
  기존 데이터베이스의 버전을 높일 때(db를 열었는데(open), 이전보다 높은 버전을 지정하는 경우)
  • 해당 이벤트가 성공하며 onsuccess 핸들러가 트리거 된다.
  • 단 indexedDB.open(name, version).onupgradeneeded와 같은 형식은 지원하지 않는다.

 

(3) 예시 코드

  • 아래 코드는 SampleDB를 열고, 해당 db에 name이라는 이름의 ObjectStore를 추가한 모습이다.
// 1. indexedDB 객체 가져오기
const idxedDB = window.indexedDB;

// 2. 브라우저에서 지원하는지 체크하기
if (!idxedDB) window.alert('해당 브라우저에서는 indexedDB를 지원하지 않습니다.')
else {
  let db;
  const request = idxedDB.open('SampleDB');   // 3. SampleDB(db) 열기

  request.onupgradeneeded =(e)=> { 
    db = e.target.result;
    db.createObjectStore('name', {keyPath: 'id'}); // 4. name저장소 만들고, key는 id로 지정
    request.onerror =(e)=> alert('failed');
    request.onsuccess =(e)=> db = request.result;  // 5. 성공시 db에 result를 저장

  }

}

 

 


 

3) 트랜잭션 시작하기

  • indexedDB.open 성공시(onsuccess), transaction을 사용해, 저장소에 데이터를 입력할 수 있다.
  • 단, 새 데이터베이스에서 작업을 하기전에 트랜잭션을 시작해야 한다!

(1) 트랜잭션은 무엇일까?

❓ 트랜잭션이 뭐길래, 이걸 먼저 시작해야할까?

  • 트랜잭션은 db의 상태르 변화시키기 위해 수행하는 작업 단위를 말한다.
  • 트랜잭션은 데이터베이스 객체 단위로 작동하며, 그렇기 때문에 사용할 객체 저장소를 지정해줘야 한다.
  • 우리는 트랜잭션을 통해, 객체 저장소에 접근하거나 데이터 요청을 할 수 있다.
  • 트랜잭션은 다음 3가지 모드가 있다.(readonlyreadwriteversionchange)

 

(2) 트랜잭션 3가지 모드

versionchange 모드

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

  • 아래와 같은 상황은 versionchange에서 처리해줘야한다.
  상황
  객체 저장소를 만들 때
  객체 저장소에서 인덱스를 만들거나 삭제할 때
  데이터베이스의 스키마나 구조를 변경할 때
  • 해당 트랙잭션은 indexedDB.open시 버전을 지정한 경우에 시작해야 한다.
  • 단, 일부 webKit 브라우저의 open()는 데이터베이스의 이름(name) 하나만 인자로 받는다.
  • 따라서 별도로 setVersion()를 호출해야 한다.

 

readonly 모드

  • 객체 저장소의 레코드를 읽을 때, readonly에서 처리해줘야한다.
  • IDBDatabase.transaction으로 해당 모드를 열 수 있다.

 

readwrite 모드

  • 아래와 같은 상황은 readwrite에서 처리해줘야한다.
  상황
  객체 저장소의 레코드를 읽을 때
  존재하는 객체 저장소에 변경점을 기록할 때
  데이터베이스의 스키마나 구조를 변경할 때
  • IDBDatabase.transaction으로 해당 모드를 열 수 있다.

 

(3) transaction() 사용하기

  • 우리는 transaction()을 사용해 특정 객체 저장소에 접근할 수 있다.
  • 모드가 지정되지 않는다면 기본적으로 트랜잭션은 readonly 모드로 열린다.
  • 해당 메소드는 객체 저장소에 접근할 수 있는 트랜잭션 객체를 반환한다.
IDBDatabase.transaction(store_names, mode, options);
// 예시
IDBDatabase.transaction(['store1', 'store2']); // 객체저장소가 여러개에 접근할 경우
IDBDatabase.transaction('store1');             // 객체저장소가 하나에 접근할 경우

 

(4) 예시 코드

function writeIdxedDB(names) {
  const request = window.indexedDB.open('SampleDB');
  request.onerror =(e)=> {
    alert('DataBase error', e.target.errorCode);
  }
  request.onsuccess =(e)=> {
    const db = request.result;
    const transaction = db.transaction(['name'], 'readwrite');  
    //person 객체 저장소에 읽기&쓰기 권한으로 transaction 생성

    // 완료, 실패 이벤트 처리
    transaction.oncomplete =(e)=> {
      console.log('success');
    }
    transaction.onerror =(e)=> {
      console.log('fail');
    }

    // transaction으로 
    const objStore = transaction.objectStore('name');
    for (const name of names) {
      const request = objStore.add(name);   // 저장
      request.onsuccess =(e)=> console.log(e.target.result);
    }  
  }
} 

const names = [{id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 3, name: 'c'}];

writeIdxedDB(names);

 

 


 

4) 본격적으로 CRUD 해보기

(1) db에서 데이터 조회하기

  • 특정 데이터값을 조회하려면 해당 데이터의 key값을 사용하면 된다.
function getIdxedDBValue(key) {
  const request = window.indexedDB.open('SampleDB');  // 1. DB 열기
  request.onerror =(e)=> console.log(e.target.errorCode);

  request.onsuccess =(e)=> {
    const db = request.result;
    const transaction = db.transaction('name');      
    transaction.onerror =(e)=> console.log('fail');
    transaction.oncomplete =(e)=> console.log('success');

    const objStore = transaction.objectStore('name');
    const objStoreRequest = objStore.get(key);        // 2. get으로 데이터 접근
    objStoreRequest.onsuccess =(e)=> {
      console.log(objStoreRequest.result)
    }
  }
}
getIdxedDBValue(1);  // { id:1, name:"a" }

 

  • 전체 데이터를 조회하려면, cursor를 사용해 데이터를 조회할 수 있다.
function getIdxedDBValues() {
  const request = window.indexedDB.open('SampleDB');      // 1. DB 열기
  request.onerror =(e)=> console.log(e.target.errorCode);

  request.onsuccess =(e)=> {
    const db = request.result;
    const transaction = db.transaction('name');
    transaction.onerror =(e)=> console.log('fail');
    transaction.oncomplete =(e)=> console.log('success');

    const objStore = transaction.objectStore('name');    // 2. name 저장소 접근
    const cursorRequest = objStore.openCursor();
    cursorRequest.onsuccess =(e)=> {
      let cursor = e.target.result;
      if (cursor) {
        const value = objStore.get(cursor.key);         // 3. 커서를 사용해 데이터 접근
        value.onsuccess =(e)=> {
          console.log(e.target.result);
        }
        cursor.continue();                              // 4. cursor로 순회
      }
    }
  }
}
getIdxedDBValues();  // { id:1, name:"a" }, {id: 2, name: 'b'}, {id: 3, name: 'c'}

 

(2) db에서 데이터 수정하기

  • put()을 사용해 db의 데이터 값을 수정할 수 있다.
function updateIdxedDBValue(key, value) {
  const request = window.indexedDB.open('SampleDB');  // 1. db 열기
  request.onerror =(e)=> console.log(e.target.errorCode);

  request.onsuccess =(e)=> {
    const db = request.result;
    const transaction = db.transaction('name', 'readwrite');
    transaction.onerror =(e)=> console.log('fail');
    transaction.oncomplete =(e)=> console.log('success');

    const objStore = transaction.objectStore('name');// 2. name 저장소 접근
    const objStoreRequest = objStore.get(key);       // 3. key값으로 데이터 접근
    objStoreRequest.onsuccess =(e)=> {
      const updateRequest = objStore.put(value);     // 4. 수정
      updateRequest.onerror =(e)=> console.log('udpate error');
            updateRequest.onsuccess =(e)=> console.log('success');
    }
  }
}
updateIdxedDBValue(1, {id: 1, name: 'vvvv'}); 
updateIdxedDBValue(2, {id: 2, name: 'bbbbb'});

 

  • 단, put을 할 때, 키(key)를 포함한 객체를 넘겨야 한다.
  • 만약 key값을 넘기지 않고 값만 바꾸고 싶다면 아래 방법을 사용하자
...
objStoreRequest.onsuccess =(e)=> {
  const data = objStoreRequest.result;      // 해당 키의 데이터 다 가져오기
  data.name = '어쩌구저쩌구로 변경';             // 데이터에서 일부 속성값 변경
  const updateRequest = objStore.put(data); // 변경된 data를 넘김  
}

 

(3) db에서 데이터 삭제하기

  • delete()를 사용해 특정 키의 값 삭제할 수 있다.
function deleteIdxedDBValue(key) {
  const request = window.indexedDB.open('SampleDB');     // 1. db 열기
  request.onerror =(e)=> console.log(e.target.errorCode);

  request.onsuccess =(e)=> {
    const db = request.result;
    const transaction = db.transaction('name', 'readwrite');
    transaction.onerror =(e)=> console.log('fail');
    transaction.oncomplete =(e)=> console.log('success');

    const objStore = transaction.objectStore('name');   // 2. name 저장소 접근
    const objStoreRequest = objStore.delete(key);       // 3. 삭제하기 
    objStoreRequest.onsuccess =(e)=> {
      console.log('deleted');
    }
  }
}
deleteIdxedDBValue(1);

 

  • clear()를 사용해 특정 저장소의 데이터 값을 모두 삭제할 수 있다.
function clearIdxedDBValue() {
  const request = window.indexedDB.open('SampleDB');     // 1. db 열기
  request.onerror =(e)=> console.log(e.target.errorCode);

  request.onsuccess =(e)=> {
    const db = request.result;
    const transaction = db.transaction('name', 'readwrite');
    transaction.onerror =(e)=> console.log('fail');
    transaction.oncomplete =(e)=> console.log('success');

    const objStore = transaction.objectStore('name');   // 2. name 저장소 접근
    const objStoreRequest = objStore.clear();           // 3. 전체 삭제
    objStoreRequest.onsuccess =(e)=> {
      console.log('cleared');
    }
  }
}
clearIdxedDBValue();

[출처] https://mong-blog.tistory.com/entry/indexedDB%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
487 [JavaScript] [JS] CORS 정리 및 오류 해결 졸리운_곰 2023.05.09 22
486 [node.js 응용] Build a Node.js Proxy Server in Under 10 minutes! file 졸리운_곰 2023.05.07 18
485 [node.js 응용] node - pm2로 node.js 프로세스 관리하기 - 기본 명령어, 실행하기 file 졸리운_곰 2023.04.25 10
484 [node.js 응용] Node.js | MySQL과 연동(mysql모듈) - CRUD 2/2 졸리운_곰 2023.03.31 7
483 [node.js 응용] Node.js | MySQL과 연동(mysql모듈) - CRUD 1/2 file 졸리운_곰 2023.03.31 8
482 [Javascript][persistent storage] persistent storage of Javascript file 졸리운_곰 2023.02.05 11
481 [JavaScript] 자바스크립트 객체 배열에서 indexOf 사용방법 졸리운_곰 2023.01.26 9
480 [HTML/Javascript] 웹소켓(WEBSOCKET) 시작하기(강의,번역) file 졸리운_곰 2022.11.15 15
479 [HTML/Javascript] 웹소켓 튜터리얼 졸리운_곰 2022.11.15 4
478 [HTML, Javascript] JavaScript에 변수가 있는지 확인 졸리운_곰 2022.11.15 10
477 [html, javascript] JavaScript에서 함수가 완료 될 때까지 기다립니다 졸리운_곰 2022.11.15 45
476 [IE javascript to Chrome] A universal createPopup() replacement 졸리운_곰 2022.11.14 8
475 [web개발][javascript] TypeScript 기본 문법 정리 졸리운_곰 2022.11.05 11
» [HTML/Javascript] indexedDB에 대해 알아보자! file 졸리운_곰 2022.09.15 57
473 [HTML][Javascript] JavaScript - DOM 요소의 생성 및 삭제, innerHTML, CSS 스타일 적용, JavaScript 스타일 적용 file 졸리운_곰 2022.09.09 9
472 [HTML] Div 를 새창 팝업으로 띄우기 졸리운_곰 2022.09.09 7
471 [Web Design][웹 디자인] Sass(SCSS) 완전 정복! 졸리운_곰 2022.07.31 91
470 [Apache 운영] 404 에러페이지 전환 How to Redirect 404 to Homepage using .htaccess 졸리운_곰 2022.07.28 46
469 [JWT} [WEB] JWT(Json Web Token)란? 개념 정리 및 예제 file 졸리운_곰 2022.07.15 38
468 [php worldpress] [위 에]wordpress 사용자 암호 화 원리 및 알고리즘 분석 졸리운_곰 2022.04.11 13
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED