当前位置: 首页 > news >正文

indexDB快速上手

目录

前言

打开 / 创建 数据库

添加数据

删除数据

更新数据

查询数据

按主键查询

范围查询(使用游标)

全部查询

cursor

getAll


前言

indexDB是浏览器内置的一种低级异步数据库,专为存储大量结构化数据而设计,属于HTML5标准的一部分。

它具备下面六个特性

  • 大容量存储:容量远远大于“localStorage”(通常为GB级别),适合存储大量数据
  • 支持复杂数据类型:支持字符串、数字、对象、数组、Blob、File等
  • 异步操作:所有操作均为异步,不会阻塞主线程,避免影响页面响应速度
  • 事务支持:基于事务的原子操作,确保一组操作要么全部成功,要么全部失败,保证数据一致性
  • 索引与查询能力:支持创建索引,可按非主键字段高效查询,支持范围查询
  • 同源隔离策略支持:遵循浏览器同源策略,不同域名的页面 / 插件无法访问彼此的indexDB数据

它具备下面五个概念

  • 数据库
    • 每个数据库有唯一名称(字符串)和版本号(正整数)
    • 版本号用于数据库结构升级(只能递增,不能递减)
  • 对象仓库(表)
    • 类似于关系数据库中的“表”,是存储数据的基本单元
    • 每个对象仓库需指定主键,用于唯一标识数据
    • 若数据无固定主键,可设置autoIncrement:true自动生成递增主键
  • 索引
    • 基于对象仓库中的字段创建,用于加速查询
    • 可指定是否唯一,避免重复值
  • 事务
    • 所有数据操作(增删改查)必须在事务中执行
    • 事务有三种模式:readonly(只读)、readwrite(读写)、versionchange(版本变更)
  • 游标
    • 用于遍历对象仓库或索引中的数据,支持按条件查询和范围查询

如果您清楚数据库的相关概念,并且使用过相关数据库(MySQL、Oracle等等),相信indexDB对您来说小菜一碟

打开 / 创建 数据库

indexDB是“无模式”数据库,即不需要在数据库表中预先定义字段,这通常表现为:

  1. 我向user表添加一条记录:{name:"李华",age:12}
  2. 再向user表添加一条记录:{gender:"男"}

此时在数据库中结构如下:

nameagegender
李华12null
nullnull

当再次添加表中没有的字段的记录时,indexDB会自动创建一个新的字段

export function createDB(){const request = indexedDB.open('extensionStudy',1)request.onupgradeneeded = (event) => {const db = event.target.result;// 若不存在users表,则创建user表if (!db.objectStoreNames.contains('users')){const userStore = db.createObjectStore("users",{keyPath:"id",autoIncrement:true})}}request.onsuccess = (event) => {const db = event.target.result;console.log("数据库打开成功",db)}request.onerror = (event) => {console.log("数据库打开失败",event.target.error)}console.log(request)
}

效果

添加数据

requeststore.add的一个回调结果,它包含下面的属性:

  • error:出错的描述会被存放在这里
  • onerror:出错时的回调
  • onsuccess:成功时的回调
  • readyState:执行状态
  • result:添加数据的主键号
  • source:来源
  • transaction:事务
export function addUser(db,userData){// 开启读写事务const transaction = db.transaction(['users'],'readwrite')const store = transaction.objectStore('users')// 添加数据const request = store.add(userData)request.onsuccess = () => {console.log("数据添加成功",request.result)}request.onerror = (event) => {console.log("数据添加失败",event.target.error)}transaction.oncomplete = () => {console.log("事务完成")}
}

效果

删除数据

删除数据时,只需要提供主键即可删除

export function deleteUser(db,id){// 开启读写事务const transaction = db.transaction(['users','readwrite'])const store = transaction.objectStore('users')const request = store.delete(id)request.onsuccess = () => {console.log("数据删除成功",request)}
}

效果

更新数据

export function updateUser(db,userData){// 需包含主键(id),否则无法定位数据const transaction = db.transaction(["users"], "readwrite");const store = transaction.objectStore("users");// put() 方法:存在则更新,不存在则新增const request = store.put(userData);request.onsuccess = () => {console.log("数据更新成功");};
}

查询数据

按主键查询

export function getUserById(db,id){const transaction = db.transaction(['users'],'readonly')const store = transaction.objectStore('users')const request = store.get(id)console.log('结果',request)request.onsuccess =() => {const user = request.resultif (user){console.log("查询结果",user)}else{console.log("查询结果为空")}}
}

效果

范围查询(使用游标)

export function getUsersByAgeRange(db,minAge,maxAge){const transaction = db.transaction(['users'],'readonly')const store = transaction.objectStore('users')// 打开游标const range = IDBKeyRange.bound(minAge,maxAge)const request = store.openCursor(range,"next")const results = []request.onsuccess = (event) => {const cursor = event.target.resultif (cursor){results.push(cursor.value)cursor.continue()}else{console.log("查询结果",results)}}
}

效果

全部查询

获取所有数据可以使用cursor也可以使用getAll方法

cursor

cursor适合大数据量数据

function getAllDataByCursor(db, storeName) {return new Promise((resolve, reject) => {const result = []; // 存储所有数据// 1. 创建只读事务const transaction = db.transaction(storeName, "readonly");const store = transaction.objectStore(storeName);// 2. 打开游标(不指定范围,默认遍历所有数据)const request = store.openCursor();// 3. 游标打开成功request.onsuccess = (event) => {const cursor = event.target.result;if (cursor) {// 收集当前数据result.push(cursor.value);// 继续下一条cursor.continue();} else {// 游标为null,遍历完成resolve(result);}};// 4. 处理错误request.onerror = (event) => {console.error("游标查询失败:", event.target.error);reject(event.target.error);};});
}

getAll

getAll适合小数据量数据

function getAllDataByGetAll(db, storeName) {return new Promise((resolve, reject) => {// 1. 创建只读事务const transaction = db.transaction(storeName, "readonly");const store = transaction.objectStore(storeName);// 2. 调用 getAll() 获取所有数据(不传入参数表示获取全部)const request = store.getAll();// 3. 处理结果request.onsuccess = () => {resolve(request.result); // request.result 直接是所有数据的数组};request.onerror = (event) => {console.error("getAll 查询失败:", event.target.error);reject(event.target.error);};});
}

http://www.dtcms.com/a/354610.html

相关文章:

  • 2015考研数学(二)真题
  • 让模糊物体变清晰的视频AI:快速提升画质指南
  • 51c大模型~合集175
  • pcl_案例2 叶片与根茎的分离
  • Redis发布订阅:实时消息系统的极简解决方案
  • MyBatis延迟加载
  • 云计算学习100天-第29天
  • Node.js 的模块化规范是什么?CommonJS 和 ES6 模块有什么区别?
  • Python DELL Logo
  • day1 ———C++———变量和字符串的使用
  • AI驱动企业数字化转型:解码未来三年的智能化变革密码
  • STAGEWISE实战指南:从集成到使用的完整解决方案
  • AI在商业领域的多元应用:从写作助手到精准运营,解锁AI商业工具新价值
  • 流程控制语句(3)
  • 操作系统中的死锁是什么意思
  • 农行广西区分行携手广西专精特新商会共探金融赋能专精特新企业新路径
  • 用KPI导航数字化转型:制造企业如何科学评估系统上线成效
  • 流程控制语句(2)
  • Java网络编程(UDP, TCP, HTTP)
  • 【Linux基础知识系列:第一百一十五篇】使用gzip与bzip2进行压缩
  • 从首次测试到采购40个机器人:Junior kühlk如何自动化协作机械臂矩阵
  • Linux学习-基于TCP实现群聊
  • 医疗AI时代的生物医学Go编程:高性能计算与精准医疗的案例分析(三)
  • windows下查看别的服务器的端口是否通
  • [光学原理与应用-319]:激光器光路设计的主要输出文件的形式和内容
  • 解构与重构:“真人不露相,露相非真人” 的存在论新解 —— 论 “真在” 的行为表达本质
  • 一文读懂:用PyTorch从零搭建一个Transformer模型
  • (LeetCode 每日一题) 3446. 按对角线进行矩阵排序(矩阵、排序)
  • 读大语言模型08计算基础设施
  • GeoScene Maps 完整入门指南:从安装到实战