indexedDB---掌握浏览器内建数据库的基本用法

1.认识indexedDB

        IndexedDB 是一个浏览器内建的数据库,它可以存放对象格式的数据,类似本地存储localstore,但是相比localStore 10MB的存储量,indexedDB可存储的数据量远超过这个数值,具体是多少呢?

默认情况下,浏览器会将自身所在的硬盘位置剩余容量全部作为indexedDB的存储容量,

这里差不多就对应这c盘的剩余容量,所以indexDB有第一个特点,容量大

存储的格式,以对象的键值形式存储数据,注意这里的 id 是一个唯一的索引属性,

在indexedDB中,需要有一个唯一的标识符来区分存储的内容,这里使用的是id,这表示,存储的每一个值内都需要一个唯一的id值,这是第二个特点,统一的唯一标识符(key)

最后它采用的是,对象存储库和存储表的数据存放方式;你可以理解成,indexedDB是一个大的数据对象(object),它内部包含了很多数据库(object),每个数据库内又有很多存储对象表(array),每个表内又有很多键值对(object),

在indexedDB中,有很多上面的这种存储库对象,可以看出这是一个树形结构,根节点就是indexedDB

所以,总结一下,indexedDB:

  1. 容量大
  2. 有唯一标识符(key)
  3. 树形结构的对象存储
  4. 和localStore一样同一个域名下的indexedDB是一致的,否则不一致,每个网页都有各自的indexedDB(补充)

2.indexedDB数据库的使用

查看indexedDB

我们可以在开发者工具中直接查看indexedDB数据库,也可以在控制台打印出来,indexedDB是window对象下的一个属性,

// 浏览器本地数据库
console.log(indexedDB);// window.indexedDB

打开数据库

const request = indexedDB.open(name, version);

name —— 字符串,即数据库名称。
version —— 一个正整数版本,默认为 1。

返回 openRequest 对象

注意:数据库的相关操作都是异步的,打开、读取和编辑、删除,都需要时间处理,并不是马上执行结束,所以每一个对数据库的相关操作都有回调事件进行监听,

  • success:打开成功,数据库准备就绪 ,request.result 中有了一个数据库对象“Database Object”,这就是一个数据库,我们可以通过它访问这个库的所有数据
  • error:打开失败。
  • upgradeneeded:更新版本,当数据库的版本更新时触发,例如,1->2。

        这里解释一下版本号,一个 数据库在打开时,若没有这个库,则会新建,默认版本号为1;若有,打开时的版本号比原本保存的版本号更高,则会更新这个库,同时触发upgradeneeded事件,一个数据库的版本号只会越来越高,不会出现还原旧版本的情况,这是因为有些特定的操作只能在版本更新时执行(upgradeneeded事件)--- 例如,新建、编辑、删除一个对象存储表

// 浏览器本地数据库
console.log(indexedDB);// window.indexedDB

// 打开数据库
const request = indexedDB.open('myDatabase', 1);

request.onerror = function(event) {
  console.error('数据库打开报错');
}

request.onupgradeneeded = function(event) {
  const db = event.target.result;
  console.log('数据库需要升级');
  // 创建一个对象存储空间
}

request.onsuccess = function(event) {
  const db = event.target.result;
  console.log('数据库打开成功');
}

 

新建了一个myDatabase数据库,触发 了一次版本更新,在次执行时版本还是1就不会触发更新升级的事件,

这样就成功新建、打开了一个数据库,

新建一个对象存储表

db.createObjectStore(name[, keyOptions]);

name 是存储区名称,例如 "books" 表示书。
keyOptions 是具有以下两个属性之一的可选对象:
    keyPath —— 对象属性的路径,IndexedDB 将以此路径作为键,例如 id。
    autoIncrement —— 如果为 true,则自动生成新存储的对象的键,键是一个不断递增的数字。
  •  name:储存表的名称
  • keyOptions: 配置对象,
    • keyPath: 储存数据的标识符
    • autoIncrement:默认为false,若为true,则会自动在储存的对象上添加标识符属性,并附上一个自增的正数值(1,2,3,4......)

要操作对象存储表就需要更新版本号,这个createObjectStore方法只能在更新事件内使用,否则将产生错误

// 打开数据库
const request = indexedDB.open('myDatabase', 2);

request.onupgradeneeded = function(event) {
  const db = event.target.result;
  console.log('数据库需要升级');
  // 创建一个对象存储空间
  
  db.createObjectStore('imgStore', { keyPath: 'id', autoIncrement: true });
  console.log('对象存储表创建成功');
}

request.onsuccess = function(event) {
  const db = event.target.result;
  console.log('数据库打开成功');
}

注意需要增加版本号,否则不触发更新事件,这里新建了一个叫imgStore的对象存储表

添加和读取数据

添加和读取数据都在onsuccess的回调中执行,不需要更新版本,

添加数据add()---参数any

request.onsuccess = function(event) {
  const db = event.target.result;
  console.log('数据库打开成功');
  // 连接数据库的表,比获取读写权限,默认只读
  const transaction = db.transaction(['imgStore'], 'readwrite');
  const objectStore = transaction.objectStore('imgStore');
  // 添加数据
  const re = objectStore.add({
    name: 'test',
    content:'测试数据'
  });
  re.onsuccess = function (event) {
    console.log('文件添加成功');
  }
}

transaction是一个事务,连接了imgStore,并开放读写权限,之后再通过事务,获取imgStore对象存储表,最后再执行add添加数据,这里添加了一个测试对象,同样添加时一个异步操作,需要回调等待结果,

这里成功添加后可以查看数据表中的内容,如果内容没有出现可以 点击刷新,看到结果后可以发现,多了一个属性id,这个就是存储对象的标识符,前面设置了自动添加,若没有设置自动添加,则需要手动的添加一个id属性,且id的值不能和其他数据相同,否则都会添加失败

读取数据get()---参数标识符的值

request.onsuccess = function(event) {
  const db = event.target.result;
  console.log('数据库打开成功');
  // 连接数据库的表,比获取读写权限,默认只读
  const transaction = db.transaction(['imgStore'], 'readwrite');
  const objectStore = transaction.objectStore('imgStore');
  // // 添加数据
  // const re = objectStore.add({
  //   name: 'test',
  //   content:'测试数据'
  // });
  // re.onsuccess = function (event) {
  //   console.log('文件添加成功');
  // }
  // 读取数据
  const re2 = objectStore.get(1);
  re2.onsuccess = function (event) {
    console.log(re2.result);
  }
}

可以看到成功读取到了id为1的数据,

示例:存储一张图片

了解了添加和读取数据,那我们可以来实现上传一张图片,保存再数据库中,

思路:通过input file 上传一个图片,再将其存为blob,再将blob转成base64存储起来

(有关blob的操作可以参考:js二进制数据,文件---blob对象_js 输出 blob-CSDN博客)

let addFile;

request.onsuccess = function (event) {
  const db = event.target.result;
  console.log('数据库打开成功');

  addFile = function (file) {
    // 连接数据库的表,比获取读写权限,默认只读
    const transaction = db.transaction(['imgStore'], 'readwrite');
    const objectStore = transaction.objectStore('imgStore');
    const re = objectStore.add(file)
    re.onsuccess = function (event) {
      console.log('文件添加成功');
    }
  }
}

const file = document.getElementById('file');
file.addEventListener('change', (event) => {
  const file = event.target.files[0];
  if (file.type == 'image/jpeg') { // 如果文件是图片
    let blob = new Blob([file], { type: 'image/jpeg' });
    let reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onload = function (event) {
      let base64 = event.target.result;
      console.log(base64);
      addFile({
        name: file.name,
        data: base64
      })
    }
  }
})

这样我们就成功存放了一个base64形式的图片文件,

然后我们可以读取出这个图片,渲染再页面上


request.onsuccess = function (event) {
  const db = event.target.result;
  console.log('数据库打开成功');

  let getFile = function(){
    // 连接数据库的表
    const transaction = db.transaction(['imgStore'], 'readonly');
    const objectStore = transaction.objectStore('imgStore');
    // 获取数据
    const re = objectStore.get(1);
    re.onsuccess = function (event) {
      console.log(re.result);
      let img = new Image();
      img.src = re.result.data;
      img.width=800;
      document.body.appendChild(img);
    }
  }
  getFile()
}

这样就成功拿到了图片,并且每次刷新后都会保留这个图片,就相当于一个能放大文件的localStore

完整代码展示

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>本地数据库</title>
</head>
<body>
    <input type="file" name="" id="file">
    
</body>
<script src="index.js"></script>
</html>

index.js 

// 浏览器本地数据库
console.log(indexedDB);// window.indexedDB
let addFile;//添加文件的方法
// 打开数据库
const request = indexedDB.open('myDatabase', 2);

request.onerror = function (event) {
  console.error('数据库打开报错');
}

request.onupgradeneeded = function (event) {
  const db = event.target.result;
  console.log('数据库需要升级');
  // 创建一个对象存储空间

  db.createObjectStore('imgStore', { keyPath: 'id', autoIncrement: true });
  console.log('对象存储表创建成功');
}

request.onsuccess = function (event) {
  const db = event.target.result;
  console.log('数据库打开成功');
  // // 连接数据库的表,获取读写权限,默认只读
  // const transaction = db.transaction(['imgStore'], 'readwrite');
  // const objectStore = transaction.objectStore('imgStore');
  // // 添加数据
  // const re = objectStore.add({
  //   name: 'test',
  //   content:'测试数据'
  // });
  // re.onsuccess = function (event) {
  //   console.log('文件添加成功');
  // }
  // 读取数据
  // const re2 = objectStore.get(1);
  // re2.onsuccess = function (event) {
  //   console.log(re2.result);
  // }

  addFile = function (file) {
    // 连接数据库的表,获取读写权限,默认只读
    const transaction = db.transaction(['imgStore'], 'readwrite');
    const objectStore = transaction.objectStore('imgStore');
    const re = objectStore.add(file)
    re.onsuccess = function (event) {
      console.log('文件添加成功');
    }
  }
  let getFile = function(){
    // 连接数据库的表
    const transaction = db.transaction(['imgStore'], 'readonly');
    const objectStore = transaction.objectStore('imgStore');
    // 获取数据
    const re = objectStore.get(1);
    re.onsuccess = function (event) {
      console.log(re.result);
      let img = new Image();
      img.src = re.result.data;
      img.width=800;
      document.body.appendChild(img);
    }
  }
  getFile()
}

const file = document.getElementById('file');
file.addEventListener('change', (event) => {
  const file = event.target.files[0];
  if (file.type == 'image/jpeg') { // 如果文件是图片
    let blob = new Blob([file], { type: 'image/jpeg' });
    let reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onload = function (event) {
      let base64 = event.target.result;
      console.log(base64);
      addFile({
        name: file.name,
        data: base64
      })
    }
  }
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/736330.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端初学java

目录 java术语 JDK Javac Java Jdb Jhat JVM JRE JAR JDK下载 运行java文件 字面量 隐式转换 强制转换 注意 运算符 &&、||、&、| Switch 程序入口 String[] args 数组 静态初始化 动态初始化 变量初始化 Java内存 方法 重载 Final 包 …

mac苹果窗口辅助工具:Magnet for mac 2.14.0中文免激活版

Magnet 是一款针对 MacOS 系统的窗口管理工具软件。它能够帮助用户更加高效地管理和组织桌面上的窗口&#xff0c;通过简单的快捷键操作&#xff0c;可以将窗口自动调整到指定的位置和大小&#xff0c;实现多窗口快速布局。Magnet 还支持多显示器环境下的窗口管理&#xff0c;可…

模拟算法讲解

模拟算法是一种基于实际情况模拟的算法&#xff0c;通过模拟现实世界中的系统或过程&#xff0c;来研究它们的性质和行为。模拟算法可以用于解决各种问题&#xff0c;包括物理模拟、经济模拟、社会模拟等。 模拟算法的基本步骤包括&#xff1a; 定义问题&#xff1a;明确需要模…

禁用/屏蔽 Chrome 默认快捷键

Chrome 有一些内置的快捷键&#xff0c;但是它并没有像其他软件一样提供管理快捷键的界面。在某些时候&#xff0c;当我们因为个人需求希望禁用 Chrome 某些快捷键时&#xff0c;又无从下手。 好在有开发者开发了 Chrome 插件&#xff0c;可以禁用 Chrome 快捷键的插件&#x…

Python中使用PyQT5库时报错:没有Qt平台插件可以初始化

一、发现问题&#xff1a;无限易pythonGo打开执行的时候报&#xff1a;“没有Qt平台插件可以初始化&#xff0c;请重新安装应用程序。”的错误&#xff0c;点击确定后无限易崩溃闪退。 二、解决问题&#xff1a; 1、重新安装依赖&#xff0c;打开CMD输入pip list&#xff0c;查…

用户态协议栈06-TCP三次握手

最近由于准备软件工程师职称考试&#xff0c;然后考完之后不小心生病了&#xff0c;都没写过DPDK的博客了。今天开始在上次架构优化的基础上增加TCP的协议栈流程。 什么是TCP 百度百科&#xff1a;TCP即传输控制协议&#xff08;Transmission Control Protocol&#xff09;是…

「动态规划」如何求环绕字符串中唯一的子字符串个数?

467. 环绕字符串中唯一的子字符串https://leetcode.cn/problems/unique-substrings-in-wraparound-string/description/ 定义字符串base为一个"abcdefghijklmnopqrstuvwxyz"无限环绕的字符串&#xff0c;所以base看起来是这样的&#xff1a;"...zabcdefghijklm…

浅谈红队攻防之道-office文件免杀

最完美的状态&#xff0c;不是你从不失误&#xff0c;而是你从没放弃成长。 ∙菜单栏&#xff1a;集成了Cobalt Strike的所有功能。 ∙快捷功能区&#xff1a;列出了常用功能。 ∙目标列表区&#xff1a;根据不同的显示模式&#xff0c;显示已获取权限的主机及目标主机。 ∙…

如何打包数据库文件

使用 mysqldump 命令&#xff1a; mysqldump -u username -p database_name > output_file.sql username 是数据库的用户名。database_name 是要导出的数据库名称。output_file.sql 是导出的 SQL 文件名&#xff0c;可以自定义。 示例&#xff1a; mysqldump -u root -p…

OS复习笔记ch12-2

辅存管理 文件分配问题 创建文件一次性分配最大空间吗&#xff1f;分配连续的分区空间&#xff0c;分区多大&#xff1f;用什么数据结构记录&#xff1f; &#xff08;1&#xff09;分配方式 类似于#ch8-3调页机制&#xff0c;文件分配也有预分配和动态分配的形式。 一般拷贝…

【database1】mysql:DDL/DML/DQL,外键约束/多表/子查询,事务/连接池

文章目录 1.mysql安装&#xff1a;存储&#xff1a;集合&#xff08;内存&#xff1a;临时&#xff09;&#xff0c;IO流&#xff08;硬盘&#xff1a;持久化&#xff09;1.1 服务端&#xff1a;双击mysql-installer-community-5.6.22.0.msi1.2 客户端&#xff1a;命令行输入my…

文华财经多空精准买卖点止损止盈数值主图指标公式源码

文华财经多空精准买卖点止损止盈数值主图指标公式源码&#xff1a; DD:EVERY(H>HV(H,20),1); KK:EVERY(L<LV(L,20),1); D:DD&&SUM(DD,BARSLAST(KK))1; K:KK&&SUM(KK,BARSLAST(DD))1; Y:1; DRAWCOLORKLINE(Y&&ISDOWN,COLORYELLOW,0); DRAW…

How to create a langchain doc from an str

问题背景&#xff1a; Ive searched all over langchain documentation on their official website but I didnt find how to create a langchain doc from a str variable in python so I searched in their GitHub code and I found this : 在 langchain 的官方文档中&#…

吴恩达机器学习 第二课 week4 决策树

目录 01 学习目标 02 实现工具 03 问题描述 04 构建决策树 05 总结 01 学习目标 &#xff08;1&#xff09;理解“熵”、“交叉熵&#xff08;信息增益&#xff09;”的概念 &#xff08;2&#xff09;掌握决策树的构建步骤与要点 02 实现工具 &#xff08;1&#xff09;…

视频讲解|【双层模型】分布式光伏储能系统的优化配置方法

1 主要内容 该讲解视频对应的程序链接为【双层模型】分布式光伏储能系统的优化配置方法&#xff0c;模型参考《分布式光伏储能系统的优化配置方法》&#xff0c;分为上下层求解方式&#xff0c;上层采用粒子群算法确定储能的选址和容量方案&#xff0c;以全年购电成本、网络损…

<router-view />标签的理解

< router-view />标签的理解 < router-view />用来承载当前级别下的子集路由的一个视图标签。显示当前路由级别下一级的页面。 App.vue是根组件&#xff0c;在它的标签里使用&#xff0c;而且配置好路由的情况下&#xff0c;就能在浏览器上显示子组件的效果。 如…

开启调试模式

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 run()方法虽然适用于启动本地的开发服务器&#xff0c;但是每次修改代码后都要手动重启它。这样并不够方便&#xff0c;如果启用了调试支持&#xff…

中国真实婚恋相亲交友服务平台有哪些?全国靠谱恋爱脱单软件APP大全

终于成功脱单了&#xff01;在过去的这两年里&#xff0c;我动用了身边所有的资源&#xff0c;却始终未能找到理想的男朋友。无奈之下&#xff0c;只好将目光转向线上。经过长达半年的不懈坚持&#xff0c;终于寻觅到了心仪的对象&#xff01;接下来&#xff0c;我要把自己用过…

【PL理论深化】(2) 语法分析 (Syntax) | 编程语言的语法结构:文法 | 语义结构 (Sematics)

&#x1f4ac; 写在前面&#xff1a;编程语言是由归纳法生成的程序的集合。定义属于该语言的程序的形式的规则&#xff0c;即编写程序的规则&#xff0c;称为编程语言的 语法分析 (syntax) 而定义属于该语言的程序的意义的规则称为 语义结构(semantics)。这两者都是归纳定义的。…

QML 列表,图片展示(一)

文章目录 1.QML 列表&#xff0c;图片展示效果图2.项目基本说明3.项目详解3.1界面显示部分3.2 网络部分 4.源代码5.flickr图片查询链接&#xff0c;后面我们将调整代码&#xff0c;获取更多图片 1.QML 列表&#xff0c;图片展示效果图 2.项目基本说明 该项目来自Qt示例程序 Ph…