IndexedDB 사용

이 가이드에서는 IndexedDB API를 사용합니다. 우리는 Jake Archibald의 프라미스 색인화된 데이터베이스 IndexedDB API와 매우 유사하지만 프라미스를 사용합니다. await를 사용하면 더 간결한 문법을 얻을 수 있습니다. 이를 통해 API가 단순화되면서 살펴봤습니다

IndexedDB란 무엇인가요?

IndexedDB는 단일 BigQuery 또는 BigQuery의 정보를 수집할 수 있습니다. 일반적인 검색, get 및 IndexedDB는 트랜잭션을 지원하며 대량의 구조화된 데이터를 저장하는 데 사용됩니다.

각 IndexedDB 데이터베이스는 origin마다 고유합니다. (일반적으로 사이트 도메인 또는 하위 도메인). 즉, 사이트에 액세스하거나 액세스할 수 없습니다. 확인할 수 있습니다 데이터 저장용량 한도 은 대개 크기가 크지만(있는 경우) 다른 브라우저에서 제한을 처리합니다. 다른 방식으로 수행할 수 있습니다 자세한 내용은 추가 자료 섹션을 참고하세요. 자세히 알아보세요.

IndexedDB 용어

데이터베이스
가장 높은 수준의 IndexedDB입니다. 여기에는 객체 저장소가 포함되며 유지하려는 데이터가 포함됩니다. 다음 명령어를 사용하여 여러 데이터베이스를 만들 수 있습니다. 사용할 수 있습니다.
객체 저장소
관계형 데이터베이스의 테이블과 마찬가지로 데이터를 저장할 개별 버킷입니다. 일반적으로 유형마다 하나의 객체 저장소가 있습니다 (JavaScript 데이터가 아님). 사용할 수 있습니다. 데이터베이스 테이블과 달리 JavaScript 데이터는 매장의 데이터 유형이 일관적일 필요는 없습니다. 예를 들어 앱이 세 사람에 대한 정보가 포함된 people 객체 스토어가 있습니다. 사람들의 연령 속성은 53, 'twenty-five', unknown일 수 있습니다.
색인
다른 객체 저장소( 참조 객체 저장소)를 데이터의 개별 속성으로 전송합니다. 색인은 이 속성으로 객체 저장소의 레코드를 검색합니다. 예를 들어 나중에 이름, 나이 또는 생각해 보세요.
작업
데이터베이스와의 상호작용입니다.
트랜잭션
데이터베이스를 보장하는 작업 또는 작업 그룹을 둘러싸는 래퍼 무결성 트랜잭션의 작업 중 하나가 실패하면 어떤 작업도 실패하지 않습니다. 트랜잭션이 실행되기 전의 상태로 돌아갑니다. 시작됐습니다 IndexedDB의 모든 읽기 또는 쓰기 작업은 트랜잭션의 일부여야 합니다. 이렇게 하면 충돌 위험 없이 원자적 읽기-수정-쓰기 작업이 가능합니다. 동시에 데이터베이스에서 작동하는 다른 스레드와 함께 작동합니다.
Cursor
데이터베이스의 여러 레코드를 반복하는 메커니즘입니다.

IndexedDB 지원을 확인하는 방법

IndexedDB는 거의 보편적으로 지원됩니다. 하지만 오래된 브라우저에서 작업하는 경우 특성 감지 지원을 받을 수 있습니다. 가장 쉬운 방법은 window 객체:

function indexedDBStuff () {
  // Check for IndexedDB support:
  if (!('indexedDB' in window)) {
    // Can't use IndexedDB
    console.log("This browser doesn't support IndexedDB");
    return;
  } else {
    // Do IndexedDB stuff here:
    // ...
  }
}

// Run IndexedDB code:
indexedDBStuff();

데이터베이스를 여는 방법

IndexedDB를 사용하면 원하는 이름으로 여러 데이터베이스를 만들 수 있습니다. 만약 데이터베이스를 열려고 할 때 데이터베이스가 존재하지 않는 경우 자동으로 생성됩니다 데이터베이스를 열려면 idb 라이브러리의 openDB() 메서드를 사용합니다.

import {openDB} from 'idb';

async function useDB () {
  // Returns a promise, which makes `idb` usable with async-await.
  const dbPromise = await openDB('example-database', version, events);
}

useDB();

이 메서드는 데이터베이스 객체로 확인되는 프로미스를 반환합니다. openDB() 메서드를 호출하고 이름, 버전 번호, 설정할 이벤트 객체를 제공하세요. 살펴보겠습니다

다음은 컨텍스트에서 openDB() 메서드를 보여주는 예입니다.

import {openDB} from 'idb';

async function useDB () {
  // Opens the first version of the 'test-db1' database.
  // If the database does not exist, it will be created.
  const dbPromise = await openDB('test-db1', 1);
}

useDB();

익명 함수 맨 위에 IndexedDB 지원 여부를 확인합니다. 이 브라우저가 IndexedDB를 지원하지 않으면 함수를 종료합니다. 함수가 openDB() 메서드를 호출하여 'test-db1'라는 데이터베이스를 엽니다. 이 예에서는 선택적 이벤트 객체를 생략하여 간단하지만 IndexedDB에서 의미 있는 작업을 수행하려면 이를 지정해야 합니다.

객체 저장소 사용 방법

IndexedDB 데이터베이스는 하나 이상의 객체 저장소를 포함하며, 각 객체에는 열과 해당 키와 연결된 데이터의 또 다른 열로 구성됩니다.

객체 저장소 만들기

체계적으로 구성된 IndexedDB 데이터베이스에는 유형마다 하나의 객체 저장소가 있어야 합니다. 지속되어야 할 때입니다 예를 들어 사용자가 프로필과 메모에는 person가 포함된 people 객체 스토어가 있을 수 있습니다. 객체 및 note 객체가 포함된 notes 객체 스토어가 있습니다.

데이터베이스 무결성을 보장하기 위해 다음에서 객체 저장소를 만들거나 삭제하는 것만 가능합니다. 이벤트 객체를 openDB() 호출에서 처리합니다. 이벤트 객체는 upgrade()를 노출합니다. 메서드를 사용하여 객체 저장소를 만들 수 있습니다. 먼저 createObjectStore() 드림 메서드를 사용하여 객체 저장소를 만듭니다.upgrade()

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('example-database', 1, {
    upgrade (db) {
      // Creates an object store:
      db.createObjectStore('storeName', options);
    }
  });
}

createStoreInDB();

이 메서드는 객체 저장소의 이름과 선택적 구성을 사용합니다. 객체를 사용하면 객체 저장소의 다양한 속성을 정의할 수 있습니다.

다음은 createObjectStore()를 사용하는 방법을 보여주는 예입니다.

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db1', 1, {
    upgrade (db) {
      console.log('Creating a new object store...');

      // Checks if the object store exists:
      if (!db.objectStoreNames.contains('people')) {
        // If the object store does not exist, create it:
        db.createObjectStore('people');
      }
    }
  });
}

createStoreInDB();

이 예에서는 이벤트 객체를 openDB() 메서드에 전달하여 다음 이벤트를 만듭니다. 이전과 마찬가지로 객체 저장소를 만드는 작업이 완료됩니다. 이벤트 객체의 upgrade() 메서드에서 찾을 수 있습니다. 하지만 브라우저에서 오류가 발생하는 경우 이미 존재하는 객체 스토어를 만들려고 할 때 createObjectStore() 메서드를 if 문으로 래핑 객체 저장소가 있는지 여부를 나타낼 수 있습니다 if 블록 내에서 다음을 호출합니다. createObjectStore(): 'firstOS'라는 객체 저장소를 만듭니다.

기본 키 정의 방법

객체 저장소를 정의할 때는 가상 머신을 생성할 수 있습니다 다음 중 하나를 정의하여 기본 키를 정의할 수 있습니다. 키 생성기를 사용하여 생성할 수 있습니다.

키 경로는 항상 존재하며 고유한 값을 포함하는 속성입니다. 대상 예를 들어 people 객체 스토어의 경우 이메일을 선택할 수 있습니다. 주소를 키 경로로 사용하세요.

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('people')) {
        db.createObjectStore('people', { keyPath: 'email' });
      }
    }
  });
}

createStoreInDB();

이 예시에서는 'people'라는 객체 저장소를 만들고 email를 할당합니다. 속성을 keyPath 옵션에서 기본 키로 설정합니다.

autoIncrement와 같은 키 생성기를 사용할 수도 있습니다. 키 생성기 는 객체 저장소에 추가된 모든 객체에 대해 고유한 값을 만듭니다. 기본적으로 키를 지정하지 않으면 IndexedDB가 키를 만들어 별도로 저장합니다. 추출해야 합니다.

다음 예시에서는 'notes'라는 객체 저장소를 만들고 기본 키가 자동 증가 번호로 자동 할당됩니다.

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('notes')) {
        db.createObjectStore('notes', { autoIncrement: true });
      }
    }
  });
}

createStoreInDB();

다음 예는 이전 예와 비슷하지만 이번에는 자동 증가 값이 'id'라는 속성에 명시적으로 할당됩니다.

import {openDB} from 'idb';

async function createStoreInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('logs')) {
        db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
      }
    }
  });
}

createStoreInDB();

키를 정의하는 데 사용할 방법을 선택하는 것은 데이터에 따라 다릅니다. 만약 데이터에는 항상 고유한 속성이 있으므로 이를 keyPath로 만들 수 있습니다. 이 고유성을 적용합니다. 그렇지 않으면 자동 증가 값을 사용합니다.

다음 코드는 객체의 다양한 방법을 보여주는 세 개의 객체 저장소를 만듭니다. 객체 저장소에서 기본 키 정의:

import {openDB} from 'idb';

async function createStoresInDB () {
  const dbPromise = await openDB('test-db2', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('people')) {
        db.createObjectStore('people', { keyPath: 'email' });
      }

      if (!db.objectStoreNames.contains('notes')) {
        db.createObjectStore('notes', { autoIncrement: true });
      }

      if (!db.objectStoreNames.contains('logs')) {
        db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
      }
    }
  });
}

createStoresInDB();

색인을 정의하는 방법

색인은 참조에서 데이터를 검색하는 데 사용되는 객체 저장소의 일종입니다. 객체 스토리지로 요청을 처리합니다. 색인은 참조 객체 내에 위치합니다. 는 동일한 데이터를 포함하고 있지만 지정된 속성을 키 경로를 사용합니다. 색인 생성은 객체 저장소를 만들 수 있으며, 객체 스토리지의 고유한 제약조건을 정의하는 데 데이터를 수집하는 데 사용됩니다

색인을 만들려면 createIndex()를 호출합니다. 메서드를 호출할 수 있습니다.

import {openDB} from 'idb';

async function createIndexInStore() {
  const dbPromise = await openDB('storeName', 1, {
    upgrade (db) {
      const objectStore = db.createObjectStore('storeName');

      objectStore.createIndex('indexName', 'property', options);
    }
  });
}

createIndexInStore();

이 메서드는 색인 객체를 만들고 반환합니다. createIndex() 메서드 객체 저장소의 인스턴스는 새 색인의 이름을 첫 번째 인수이며, 두 번째 인수는 지정하려는 데이터의 속성을 나타냅니다. 색인 마지막 인수를 사용하면 uniquemultiEntry가 작동합니다. uniquetrue로 설정된 경우 색인은 단일 키에 중복 값을 허용하지 않습니다. 다음으로 multiEntry 색인이 생성된 속성이 배열일 때 createIndex()의 동작을 결정합니다. 만약 true로 설정되어 있으면 createIndex()는 각 배열의 색인에 항목을 추가합니다. 요소가 포함됩니다. 그렇지 않으면 배열을 포함하는 단일 항목을 추가합니다.

예를 들면 다음과 같습니다.

import {openDB} from 'idb';

async function createIndexesInStores () {
  const dbPromise = await openDB('test-db3', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('people')) {
        const peopleObjectStore = db.createObjectStore('people', { keyPath: 'email' });

        peopleObjectStore.createIndex('gender', 'gender', { unique: false });
        peopleObjectStore.createIndex('ssn', 'ssn', { unique: true });
      }

      if (!db.objectStoreNames.contains('notes')) {
        const notesObjectStore = db.createObjectStore('notes', { autoIncrement: true });

        notesObjectStore.createIndex('title', 'title', { unique: false });
      }

      if (!db.objectStoreNames.contains('logs')) {
        const logsObjectStore = db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
      }
    }
  });
}

createIndexesInStores();

이 예시에서 'people''notes' 객체 저장소에는 색인이 있습니다. 받는사람 색인을 만들고 먼저 createObjectStore()의 결과 (객체 저장 객체)를 변수에 추가하여 createIndex()을 호출할 수 있습니다.

데이터 작업 방법

이 섹션에서는 데이터를 만들고 읽고 업데이트하고 삭제하는 방법을 설명합니다. 이러한 작업은 모두 비동기식이며 IndexedDB API가 사용하는 프라미스를 사용합니다. 요청을 처리합니다 이렇게 하면 API가 간소화됩니다. 다음에 의해 트리거된 이벤트를 수신 대기하는 대신 호출 시 다음에서 반환된 데이터베이스 객체에서 .then()를 호출할 수 있습니다. openDB() 메서드로 데이터베이스와의 상호작용을 시작하거나 await 만들 수 있습니다.

IndexedDB의 모든 데이터 작업은 트랜잭션 내에서 수행됩니다. 각 연산의 형식은 다음과 같습니다.

  1. 데이터베이스 객체를 가져옵니다.
  2. 데이터베이스에서 트랜잭션을 엽니다.
  3. 트랜잭션 시 객체 스토어 열기
  4. 객체 저장소에서 작업을 수행합니다.

트랜잭션은 작업 또는 그룹을 둘러싼 안전한 래퍼로 생각할 수 있습니다. 사용됩니다. 트랜잭션 내 작업 중 하나가 실패하면 모든 롤백됩니다 트랜잭션은 하나 이상의 객체 저장소에 따라 달라지지만 이 속성은 거래를 열 때 정의할 수 있습니다 읽기 전용 또는 읽기로 구성될 수 있습니다. 작성할 수 있습니다. 이것은 트랜잭션 내의 작업이 데이터베이스에 변경사항을 적용할 수 있습니다

데이터 생성

데이터를 만들려면 add()를 호출합니다. 메서드를 호출하고 추가하려는 데이터를 전달합니다. add() 메서드의 첫 번째 인수는 데이터를 추가할 객체 저장소입니다. 두 번째 인수는 원하는 필드 및 관련 데이터를 포함하는 객체입니다. 추가할 수 있습니다. 다음은 단일 데이터 행을 추가하는 가장 간단한 예입니다.

import {openDB} from 'idb';

async function addItemToStore () {
  const db = await openDB('example-database', 1);

  await db.add('storeName', {
    field: 'data'
  });
}

addItemToStore();

add() 호출은 트랜잭션 내에서 발생하므로 프로미스가 해결되더라도 작업이 완료되었다는 의미는 아닙니다. 그러기 위해서는 추가 작업이 수행된 경우 전체 애플리케이션이 transaction.done() 메서드를 사용하여 완료된 것입니다. 이것은 프라미스가 처리되고 트랜잭션 오류입니다 모든 '쓰기'에 대해 이 검사를 수행해야 합니다. 작업, 그것이 데이터베이스의 변경 사항이 실제로 변경되었는지 알 수 있는 유일한 방법이기 때문입니다. 확인할 수 있습니다

다음 코드는 트랜잭션 내에서 add() 메서드를 사용하는 방법을 보여줍니다.

import {openDB} from 'idb';

async function addItemsToStore () {
  const db = await openDB('test-db4', 1, {
    upgrade (db) {
      if (!db.objectStoreNames.contains('foods')) {
        db.createObjectStore('foods', { keyPath: 'name' });
      }
    }
  });
  
  // Create a transaction on the 'foods' store in read/write mode:
  const tx = db.transaction('foods', 'readwrite');

  // Add multiple items to the 'foods' store in a single transaction:
  await Promise.all([
    tx.store.add({
      name: 'Sandwich',
      price: 4.99,
      description: 'A very tasty sandwich!',
      created: new Date().getTime(),
    }),
    tx.store.add({
      name: 'Eggs',
      price: 2.99,
      description: 'Some nice eggs you can cook up!',
      created: new Date().getTime(),
    }),
    tx.done
  ]);
}

addItemsToStore();

데이터베이스를 열고 필요한 경우 객체 저장소를 만든 후에는 transaction() 메서드를 호출하여 트랜잭션을 엽니다. 이 방법 는 거래할 매장과 모드에 대한 인수를 사용합니다. 이 경우에는 스토어에 작성하는 데 관심이 있으므로 이 예는 'readwrite'는 지정합니다.

다음 단계는 거래의 일부로 스토어에 상품을 추가하는 것입니다. 앞의 예에서는 'foods'의 세 가지 작업을 처리합니다. 프라미스를 반환합니다.

  1. 맛있는 샌드위치에 대한 기록을 추가합니다.
  2. 달걀에 대한 기록을 추가합니다.
  3. 트랜잭션이 완료되었음을 알립니다 (tx.done).

이러한 모든 작업은 약속을 기반으로 하기 때문에 마무리할 수 있습니다. 이러한 프라미스를 Promise.all 드림 인체 공학적인 방법으로 이 작업을 수행할 수 있습니다. Promise.all는 프로미스에 전달된 모든 프라미스가 해결되면 종료됩니다.

추가되는 레코드 2개의 경우 트랜잭션 인스턴스의 store 인터페이스 add()를 호출하고 데이터를 전달합니다. Promise.all 통화를 await할 수 있습니다. 트랜잭션이 완료되면 완료됩니다.

데이터 읽기

데이터를 읽으려면 get()를 호출합니다. 메서드를 호출합니다.openDB() get()는 매장의 이름과 사용자가 만든 객체의 기본 키 값을 가져옵니다. 가져올 수 있습니다 다음은 기본적인 예입니다.

import {openDB} from 'idb';

async function getItemFromStore () {
  const db = await openDB('example-database', 1);

  // Get a value from the object store by its primary key value:
  const value = await db.get('storeName', 'unique-primary-key-value');
}

getItemFromStore();

add()와 마찬가지로 get() 메서드는 프로미스를 반환하므로 다음과 같은 경우 await할 수 있습니다. 원한다면 프로미스의 .then() 콜백을 사용할 수도 있습니다.

다음 예에서는 get() 메서드를 'test-db4' 데이터베이스 'foods' 객체 저장소를 사용하여 'name' 기본 키로 단일 행을 가져옵니다.

import {openDB} from 'idb';

async function getItemFromStore () {
  const db = await openDB('test-db4', 1);
  const value = await db.get('foods', 'Sandwich');

  console.dir(value);
}

getItemFromStore();

데이터베이스에서 단일 행을 검색하는 것은 매우 간단합니다. 데이터베이스에 저장하고 생성하는 행의 객체 저장소와 기본 키 값을 선택할 수 있습니다 get() 메서드가 프로미스를 반환하므로 다음 작업을 수행할 수 있습니다. await.

데이터 업데이트

데이터를 업데이트하려면 put()를 호출합니다. 메서드를 사용할 수 있습니다. put() 메서드는 add() 메서드와 비슷합니다. add() 대신 사용하여 데이터를 만들 수도 있습니다. 이 예시에서는 put()를 사용하여 기본 키 값으로 객체 저장소의 행을 업데이트하는 방법입니다.

import {openDB} from 'idb';

async function updateItemInStore () {
  const db = await openDB('example-database', 1);

  // Update a value from in an object store with an inline key:
  await db.put('storeName', { inlineKeyName: 'newValue' });

  // Update a value from in an object store with an out-of-line key.
  // In this case, the out-of-line key value is 1, which is the
  // auto-incremented value.
  await db.put('otherStoreName', { field: 'value' }, 1);
}

updateItemInStore();

다른 메서드와 마찬가지로 이 메서드는 프로미스를 반환합니다. 다음으로 put()를 사용할 수도 있습니다. 거래 중 하나입니다. 다음은 이전 'foods' 저장소를 사용하는 예입니다. 샌드위치와 계란의 가격을 업데이트합니다.

import {openDB} from 'idb';

async function updateItemsInStore () {
  const db = await openDB('test-db4', 1);
  
  // Create a transaction on the 'foods' store in read/write mode:
  const tx = db.transaction('foods', 'readwrite');

  // Update multiple items in the 'foods' store in a single transaction:
  await Promise.all([
    tx.store.put({
      name: 'Sandwich',
      price: 5.99,
      description: 'A MORE tasty sandwich!',
      updated: new Date().getTime() // This creates a new field
    }),
    tx.store.put({
      name: 'Eggs',
      price: 3.99,
      description: 'Some even NICER eggs you can cook up!',
      updated: new Date().getTime() // This creates a new field
    }),
    tx.done
  ]);
}

updateItemsInStore();

항목이 업데이트되는 방법은 키를 설정하는 방법에 따라 다릅니다. keyPath를 설정하는 경우 객체 저장소의 각 행은 인라인 키와 연결됩니다. 위의 예제는 이 키를 기반으로 행을 업데이트하며 이 이 경우 해당 키를 지정하여 객체 저장소입니다 다음과 같이 설정하여 외부 키를 만들 수도 있습니다. autoIncrement를 기본 키로 설정합니다.

데이터 삭제

데이터를 삭제하려면 delete()를 호출합니다. 메서드를 사용합니다.

import {openDB} from 'idb';

async function deleteItemFromStore () {
  const db = await openDB('example-database', 1);

  // Delete a value 
  await db.delete('storeName', 'primary-key-value');
}

deleteItemFromStore();

add()put()와 같이 이 속성을 거래의 일부로 사용할 수 있습니다.

import {openDB} from 'idb';

async function deleteItemsFromStore () {
  const db = await openDB('test-db4', 1);
  
  // Create a transaction on the 'foods' store in read/write mode:
  const tx = db.transaction('foods', 'readwrite');

  // Delete multiple items from the 'foods' store in a single transaction:
  await Promise.all([
    tx.store.delete('Sandwich'),
    tx.store.delete('Eggs'),
    tx.done
  ]);
}

deleteItemsFromStore();

데이터베이스 상호작용의 구조는 다른 데이터베이스 상호작용과 동일함 작업을 수행할 수 있습니다 다음 날짜까지 전체 거래가 완료되었는지 확인하시기 바랍니다. Promise.all에 전달하는 배열에 tx.done 메서드를 포함합니다.

모든 데이터 가져오기

지금까지는 한 번에 하나씩만 스토어에서 객체를 가져왔습니다. 그 외에 사용하여 객체 저장소 또는 색인에서 모든 데이터 또는 하위 집합을 검색할 수 있습니다. getAll() 메서드 또는 커서를 사용합니다.

getAll() 메서드

객체 저장소의 모든 데이터를 검색하는 가장 간단한 방법은 getAll()를 호출하는 것입니다. 색인에서 삭제할 수 있습니다.

import {openDB} from 'idb';

async function getAllItemsFromStore () {
  const db = await openDB('test-db4', 1);

  // Get all values from the designated object store:
  const allValues = await db.getAll('storeName');

  console.dir(allValues);
}

getAllItemsFromStore();

이 메서드는 객체 저장소의 모든 객체를 제약 조건 없이 반환합니다. 전혀. 객체 저장소에서 모든 값을 가져오는 가장 직접적인 방법입니다. 가장 유연하지 않죠

import {openDB} from 'idb';

async function getAllItemsFromStore () {
  const db = await openDB('test-db4', 1);

  // Get all values from the designated object store:
  const allValues = await db.getAll('foods');

  console.dir(allValues);
}

getAllItemsFromStore();

이 예시에서는 'foods' 객체 저장소에서 getAll()를 호출합니다. 이렇게 하면 'foods'의 객체(기본 키 순으로 정렬됨)

커서 사용 방법

커서는 여러 객체를 검색하는 더 유연한 방법입니다. 커서는 사용자는 객체 저장소에서 각 객체에 대한 해당 데이터가 선택되면 데이터와 함께 표시됩니다. 커서는 다른 데이터베이스 작업과 마찬가지로 트랜잭션에서 작동하지 않습니다.

커서를 만들려면 openCursor()를 호출합니다. 객체 저장소에 저장됩니다 다음에서 'foods' 스토어 사용 이 것이 그래프의 모든 데이터 행에서 커서를 이동시키는 방법입니다. 객체 저장소인

import {openDB} from 'idb';

async function getAllItemsFromStoreWithCursor () {
  const db = await openDB('test-db4', 1);
  const tx = await db.transaction('foods', 'readonly');

  // Open a cursor on the designated object store:
  let cursor = await tx.store.openCursor();

  // Iterate on the cursor, row by row:
  while (cursor) {
    // Show the data in the row at the current cursor position:
    console.log(cursor.key, cursor.value);

    // Advance the cursor to the next row:
    cursor = await cursor.continue();
  }
}

getAllItemsFromStoreWithCursor();

이 경우 트랜잭션은 'readonly' 모드에서 열립니다. openCursor 메서드가 호출됩니다. 후속 while 루프에서 커서의 현재 위치는 keyvalue 속성을 읽을 수 있습니다. 비즈니스에 가장 적합한 방식으로 이러한 값에 대해 작업할 수 있습니다. 있습니다. 준비가 되면 cursor 객체의 continue()를 호출할 수 있습니다. 메서드를 호출하여 다음 행으로 이동하며 커서가 서 있는 셀에 놓이면 while 루프가 종료됩니다. 데이터 세트의 끝에 도달합니다

범위 및 색인과 함께 커서 사용

색인을 사용하면 기본 키입니다. keyPath가 되는 모든 속성에 색인을 만들 수 있습니다. 를 사용하고 해당 속성의 범위를 지정하고 getAll() 또는 커서를 사용하여 범위를 지정할 수 있습니다.

IDBKeyRange 객체를 사용하여 범위를 정의합니다. 및 다음 중 하나 메서드:

upperBound()lowerBound() 메서드는 상한과 하한을 지정합니다. 표시됩니다.

IDBKeyRange.lowerBound(indexKey);

또는

IDBKeyRange.upperBound(indexKey);

각 함수는 원하는 항목에 대한 색인의 keyPath 값인 인수를 하나만 사용합니다. 상한 또는 하한으로 지정합니다

bound() 메서드는 상한과 하한을 모두 지정합니다.

IDBKeyRange.bound(lowerIndexKey, upperIndexKey);

이러한 함수의 범위는 기본적으로 포괄적입니다. 즉, 범위의 한도로 지정된 데이터입니다. 이러한 값을 생략하려면 true를 두 번째 인수로 전달하여 범위를 제외로 지정합니다. lowerBound() 또는 upperBound(), 또는 다음의 세 번째 및 네 번째 인수로 bound(): 각각 하한 및 상한

다음 예시에서는 'foods' 객체의 'price' 속성에 색인을 사용합니다. 있습니다. 이제 매장에는 상한과 하한을 나타냅니다. 다음 코드를 사용하여 두 한도 사이에서 책정됩니다.

import {openDB} from 'idb';

async function searchItems (lower, upper) {
  if (!lower === '' && upper === '') {
    return;
  }

  let range;

  if (lower !== '' && upper !== '') {
    range = IDBKeyRange.bound(lower, upper);
  } else if (lower === '') {
    range = IDBKeyRange.upperBound(upper);
  } else {
    range = IDBKeyRange.lowerBound(lower);
  }

  const db = await openDB('test-db4', 1);
  const tx = await db.transaction('foods', 'readonly');
  const index = tx.store.index('price');

  // Open a cursor on the designated object store:
  let cursor = await index.openCursor(range);

  if (!cursor) {
    return;
  }

  // Iterate on the cursor, row by row:
  while (cursor) {
    // Show the data in the row at the current cursor position:
    console.log(cursor.key, cursor.value);

    // Advance the cursor to the next row:
    cursor = await cursor.continue();
  }
}

// Get items priced between one and four dollars:
searchItems(1.00, 4.00);

예시 코드는 먼저 한도 값을 가져와 한도가 존재해야 합니다. 다음 코드 블록은 범위를 제한하는 데 사용할 메서드를 결정합니다. 자동으로 계산됩니다. 데이터베이스 상호작용에서 객체 저장소를 엽니다. 트랜잭션을 정상적으로 실행한 다음 객체 저장소에서 'price' 색인을 엽니다. 이 'price' 색인을 사용하면 가격으로 항목을 검색할 수 있습니다.

그런 다음 코드가 색인에서 커서를 열고 범위를 전달합니다. 커서 범위의 첫 번째 객체를 나타내는 프로미스를 반환하거나 다음인 경우 undefined을 반환합니다. 범위 내에 데이터가 없는 것입니다. cursor.continue() 메서드는 커서가 표시되고 커서가 도착할 때까지 루프를 계속합니다. 범위 끝에 도달해야 합니다.

데이터베이스 버전 관리

openDB() 메서드를 호출할 때 데이터베이스 버전 번호를 지정할 수 있습니다. 를 두 번째 매개변수에 추가합니다. 이 가이드의 모든 예시에서 버전은 1로 설정되어 있지만 필요한 경우 데이터베이스를 새 버전으로 업그레이드할 수 있습니다. 어떤 식으로든 수정할 수 있습니다. 지정된 버전이 기존 데이터베이스가 발생하면 이벤트 객체의 upgrade 콜백이 실행됩니다. 데이터베이스에 새 객체 저장소와 색인을 추가할 수 있습니다.

upgrade 콜백의 db 객체에는 특별한 oldVersion 속성이 있습니다. 브라우저가 액세스할 수 있는 데이터베이스의 버전 번호를 나타냅니다. 이 버전 번호를 switch 문에 전달하여 기존 데이터베이스 버전을 기반으로 하는 upgrade 콜백 내의 코드 있습니다. 예를 들면 다음과 같습니다.

import {openDB} from 'idb';

const db = await openDB('example-database', 2, {
  upgrade (db, oldVersion) {
    switch (oldVersion) {
      case 0:
        // Create first object store:
        db.createObjectStore('store', { keyPath: 'name' });

      case 1:
        // Get the original object store, and create an index on it:
        const tx = await db.transaction('store', 'readwrite');
        tx.store.createIndex('name', 'name');
    }
  }
});

이 예시에서는 데이터베이스의 최신 버전을 2로 설정합니다. 이 코드가 데이터베이스가 아직 브라우저에 존재하지 않으므로 oldVersion0이며 switch 문은 case 0에서 시작합니다. 이 예에서 'store' 객체 저장소를 데이터베이스에 추가합니다.

핵심 사항: switch 문에서는 일반적으로 각 case 뒤에 break가 있습니다. 의도적으로 여기서 사용되지 않습니다. 이렇게 하면 기존 데이터베이스 버전이 몇 버전 뒤떨어져 있거나, 존재하지 않는 경우 코드가 최신 상태가 될 때까지 case 블록의 나머지 부분을 통과합니다. 이 예에서 브라우저는 case 1까지 계속 실행되어 name store 객체 스토어입니다.

'store' 객체 저장소에 'description' 색인을 만들려면 다음을 업데이트합니다. 다음과 같이 새 case 블록을 추가합니다.

import {openDB} from 'idb';

const db = await openDB('example-database', 3, {
  upgrade (db, oldVersion) {
    switch (oldVersion) {
      case 0:
        // Create first object store:
        db.createObjectStore('store', { keyPath: 'name' });

      case 1:
        // Get the original object store, and create an index on it:
        const tx = await db.transaction('store', 'readwrite');
        tx.store.createIndex('name', 'name');

      case 2:
        const tx = await db.transaction('store', 'readwrite');
        tx.store.createIndex('description', 'description');
    }
  }
});

이전 예에서 만든 데이터베이스가 여전히 브라우저에 있는 경우 실행 시 oldVersion2입니다. 브라우저가 case 0를 건너뛰고 case 1를 실행하고 case 2에서 코드를 실행하여 description를 만듭니다. 색인 그런 다음 브라우저에는 버전 3에서 store을 포함하는 데이터베이스가 있습니다. namedescription 색인이 있는 객체 저장소

추가 자료

다음 리소스는 IndexedDB 사용에 대한 자세한 정보와 컨텍스트를 제공합니다.

IndexedDB 문서

데이터 스토리지 한도