IndexedDB에서 데이터를 효율적으로 검색하고 조작하는데 KeyRange, Index, OpenCursor를 사용할 수 있다.
KeyRange
인덱스나 객체 저장소에서 키의 범위를 제한하는 역할을 한다. 이를 통해 특정 키 값이나 범위에 해당하는 항목만 선택할 수 있다. IDBKeyRange를 통해서 사용한다.
함수 | 설명 |
lowerBound(value, lowerOpen) | 조회하려는 최소값 지정, lowerOpen이 true일 경우 값을 포함하지않음 |
upperBound(value, upperOpen) | 조회하려는 최대값 지정, upperOpen이 true일 경우 값을 포함하지않음 |
bound(lower, upper, lowerOpen, upperOpen) |
조회하려는 최대값과 최소값 지정 |
only(value) | 특정 값에 해당 하는 항목을 조회 |
includes(value) | value가 지정된 키레인지의 범위에 포함되는 지를 확인 |
// 데이터 추가
const transaction = db.transaction("customer", "readwrite");
const store = transaction.objectStore("customer");
// 예시 데이터 추가
store.add({ name: "김아무개", age: 30 });
store.add({ name: "이몽룡", age: 25 });
store.add({ name: "신데렐라", age: 35 });
// 특정 범위의 데이터 검색
const range = IDBKeyRange.bound(1, 3, true, false); // ID가 1 초과 3 이하인 항목 선택
<<전체 코드>>
더보기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IndexedDB KeyRange Example</title>
</head>
<body>
<script>
const db_name = "reservationDB";
const db_version = 1;
const request = indexedDB.open(db_name, db_version);
request.onupgradeneeded = (e) => {
const db = e.target.result;
if (!db.objectStoreNames.contains("customer")) {
db.createObjectStore("customer", {
keyPath: "id",
autoIncrement: true
});
}
};
request.onsuccess = (e) => {
const db = e.target.result;
console.log("IndexedDB를 여는 것을 성공했습니다.");
// 데이터 추가
const transaction = db.transaction("customer", "readwrite");
const store = transaction.objectStore("customer");
// 예시 데이터 추가
store.add({ name: "김아무개", age: 30 });
store.add({ name: "이몽룡", age: 25 });
store.add({ name: "신데렐라", age: 35 });
// 특정 범위의 데이터 검색
const range = IDBKeyRange.bound(1, 3, true, false); // ID가 1 초과 3 이하인 항목 선택
const request = store.openCursor(range);
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
console.log("이름:", cursor.value.name, "나이:", cursor.value.age);
cursor.continue(); // 다음 항목으로 이동
} else {
console.log("모든 항목을 순회했습니다.");
}
};
};
request.onerror = () => {
console.log("IndexedDB를 여는 것을 실패했습니다.");
};
</script>
</body>
</html>
IndexedDB에 저장되어있는 값
IndexedDB에서 bound를 통해 id가 1초과 3이하인 값만 불러옴
Index
객체 저장소의 속성에 기반하여 데이터에 대한 추가적인 검색 기능을 제공한다. 기본적으로 객체 저장소를 생성할 때 설정한 keyPath가 인덱스로 사용되지만, 특정 속성(예: 출판 연도, 제목 등)을 기준으로 검색하려면 추가적인 인덱스를 생성해야 한다. createIndex의 경우에는 versionChange 에서 호출되어야 하기 때문에 인덱스 생성은 upgradeneeded 이벤트 핸들러 내에서 이루어져야 한다.
- 스토어명.createIndex("기준 속성", "인덱스 이름", {unique: false | true })
unique의 값이 true일 경우 인덱스 값은 중복될 수 없다.
request.onupgradeneeded = (e) => {
const db = e.target.result;
if (!db.objectStoreNames.contains("books")) {
const objectStore = db.createObjectStore("books", {
keyPath: "id",
autoIncrement: true
});
// year에 대한 인덱스 생성
objectStore.createIndex("year", "year", { unique: false });
}
};
year이라는 index가 생성된 모습을 볼 수 있다.
openCursor()
객체 저장소(object store)나 인덱스(index)에서 데이터 항목을 순회한다. 커서를 사용하면 데이터베이스의 여러 항목을 효과적으로 조회하고, 각 항목에 대해 필요한 작업을 수행할 수 있다.
속성 | 설명 |
source | 커서가 오픈된 오브젝트 스토어나 인덱스 객체를 나타냄 |
direction | 커서의 진행 방법 next : 조회한 조건에 대해 오름차순으로 정렬 ( 기본값 ) nextunique : 조회한 조건에 대해 오름차순으로 정렬하며, 키가 중복되는 경우 처음 자료만 조회 prev : 조회한 조건에 대해 내림차순으로 정렬 prevunique : 조회한 조건에 대해 내림차순으로 정렬하며, 키가 중복되는 경우 처음 자료만 조회 |
key | 커서에 사용된 속성의 값을 나타냄 |
primaryKey | 조회된 자료의 keypath 속성값을 나타냄 |
value | 현재 가리키는 객체를 반환 |
함수 | 설명 |
advance(count) | 커서의 포인터를 count만큼 이동 |
continue() | 커서의 현재 포인터에서 다음 위치로 이동, IDBRequest와 success이벤트 발생시킴 |
delete() | 커서 위치에 있는 객체를 삭제 |
update(value) | 커서 위치에 있는 객체의 내용을 value 값으로 수정 |
const query = index.openCursor(range); // year인덱스 store의 범위 지정
query.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
console.log("제목:", cursor.value.title, "연도:", cursor.value.year);
cursor.continue(); // 다음 항목으로 이동
} else {
console.log("모든 항목을 순회했습니다.");
}
};
"year" 인덱스에 KeyRange를 사용하여 1990 ~ 2002 년도 범위를 설정하고, openCursor를 통해 순회하여 해당 결과에 대해 콘솔로 출력하였다.
<<전체 코드>>
더보기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IndexedDB KeyRange Example</title>
</head>
<body>
<script>
const db_name = "bookDB";
const db_version = 1;
const request = indexedDB.open(db_name, db_version);
request.onupgradeneeded = (e) => {
const db = e.target.result;
if (!db.objectStoreNames.contains("books")) {
const objectStore = db.createObjectStore("books", {
keyPath: "id",
autoIncrement: true
});
// year에 대한 인덱스 생성
objectStore.createIndex("year", "year", { unique: false });
}
};
request.onsuccess = (e) => {
const db = e.target.result;
console.log("IndexedDB를 여는 것을 성공했습니다.");
// 데이터 추가
const transaction = db.transaction("books", "readwrite");
const store = transaction.objectStore("books");
// 예시 데이터 추가
store.add({ title: "신데렐라", year: 2002 });
store.add({ title: "백설공주", year: 1994 });
store.add({ title: "잠자는 숲속의 공주", year: 2023 });
const range = IDBKeyRange.bound(1990, 2002); // 1990 ~ 2002 사이의 range 설정
const index = store.index("year"); // store의 year 인덱스를 가져옴
const query = index.openCursor(range); // year인덱스 store의 범위 지정
query.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
console.log("제목:", cursor.value.title, "연도:", cursor.value.year);
cursor.continue(); // 다음 항목으로 이동
} else {
console.log("모든 항목을 순회했습니다.");
}
};
};
request.onerror = () => {
console.log("IndexedDB를 여는 것을 실패했습니다.");
};
</script>
</body>
</html>
'Frontend > JavaScript' 카테고리의 다른 글
JavaScript : JSON(JavaScript Object Notation)에 대하여 (0) | 2024.09.02 |
---|---|
JavaScript : 웹 스토리지 (2) - IndexedDB란? (0) | 2024.08.18 |
JavaScript : 웹 스토리지 (1) - Cookie와 Web Storage (0) | 2024.08.17 |
JavaScript: location 객체란? (0) | 2024.08.15 |
JavaScript: Screen 객체 (0) | 2024.08.15 |
JavaScript : 모듈(module)에 대해서 (0) | 2024.08.14 |
JavaScript : 비동기 통신에 대해서 (Fetch & Axios) (0) | 2024.08.14 |
JavaScript : 비동기를 처리하는 방법 (Async / Await) (0) | 2024.08.13 |