indexedDB---浏览器本地数据库实现增删改查

关于indexedDB

indexedDB的基本使用,可以参考:indexedDB---掌握浏览器内建数据库的基本用法_indexdb浏览器使用-CSDN博客

indexedDB是浏览器本地数据库,既然是数据库就能够实现增删改查,了解了indexedDB的基本使用后,我们来实现它的增删改查功能

示例

这里使用音频文件上传的的示例,来演示本地数据库的增删改查功能,

整体要实现的功能简介:

        能够上传歌曲信息并存入数据库,可以从数据库中读取信息,并渲染出音频,可以对数据库的内容进行删除修改

<!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" multiple> --><div><label for="file">存储歌曲</label><input type="file" name="" id="file" style="display: none;"><input type="number" name="" value="1" id="index" style="width: 40px;"><button id="bt">获取歌曲</button><button id="del">删除歌曲</button><label for="update">修改歌曲</label><input type="file" name="" id="update" style="display: none;"></div><script src="db.js"></script><script src="file.js"></script>
</body></html>

html部分主要包括5个交互,

  1. 文件上传存储到数据库(增)
  2. 一个索引框
  3. 根据索引获取上传的音频并渲染在页面(查)
  4. 根据索引删除数据库中的歌曲(删)
  5. 上传一个文件根据索引覆盖数据库中的数据对象(改)

还有一个修改数据对象值的方法,本示例中只提供了逻辑,没有实现交互,

 file.js交互的逻辑,input上传文件处理,按钮事件处理;

db.js数据库的逻辑操作,以下是主体结构


// 浏览器本地数据库
console.log(indexedDB);// window.indexedDB// 使用indexedDB来存储文件。
// 打开数据库
const request = indexedDB.open('FileDatabase', 4);
let addFile;//添加文件的方法
let getFile;//读取文件的方法
let delFile;//删除文件的方法
let updateFile;//更新文件的方法
let updataVal;//更新文件对象值的方法
let getAllFile;//获取所有文件的方法request.onerror = function (event) {console.error('数据库打开失败:', event.target.errorCode);}request.onupgradeneeded = function (event) {const db = event.target.result;// 创建一个存储对象db.createObjectStore('FileStore', { keyPath: 'id', autoIncrement: true });console.log('数据库储存对象(表)创建成功');// // 删除一个存储对象,只能在更新版本时删除// db.deleteObjectStore('FileStore');// console.log('数据库储存对象(表)删除成功');
}request.onsuccess = function (e) {const db = e.target.result;console.log('数据库打开成功', db);// 添加文件// 读取文件// 删除文件// 更新文件// 获取所有文件}

 添加文件

file.js

const file = document.getElementById('file');// 添加歌曲
file.onchange = () => {console.log(file.files);for (item of file.files) {if (item.type == 'audio/mpeg') {console.log('音频文件');let blob = new Blob([item], { type: 'audio/mpeg' });let reader = new FileReader();reader.readAsDataURL(blob);reader.onload = () => {//读取的过程是异步的// console.log(reader.result);addFile({name: item.name,size: item.size,type: item.type,data: reader.result})// getAllFile();}}else{alert('请选择音频文件');}// if (item.type == 'image/jpeg') {//   console.log('图片文件');//   let blob = new Blob([item], { type: 'image/jpeg' });//   console.log(blob);//   let url = URL.createObjectURL(blob);//   console.log(url);//   let img = document.createElement('img');//   img.src = url;//   img.width = 200;//   document.body.appendChild(img);// }// if (item.size > 1024 * 1024 * 2) {//   console.log('文件大于2mb');// }}}

       代码逻辑: 监听onchange事件,上传选择文件后触发,匹配音频类文件,读取到file类型数据(这里可以直接用file,不需要转blob也行,我这里转blob纯属多余操作),转成base64的data:url,然后将这个data:url和文件的其他数据,构成一个对象存入数据库

{

不熟悉blob和file操作可以参考:

js二进制数据,文件---blob对象_js 输出 blob-CSDN博客

js文件---file和fileReafer对象_js file-CSDN博客

}

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

代码解读:获取事务连接,连接数据库的表,并获取读写权限,

获取数据对象表的实例

通过add方法添加一个对象到FileStore的表中,这个过程是异步的要等待结构

 

成功保存了数据,可以在控制台查看

获取文件

file.js

// 获取歌曲
document.getElementById('bt').onclick = () => {getFile(Number(index.value),getAudio);
};const getAudio = (res) => {let span = document.createElement('span');span.innerText = res.name;document.body.appendChild(span);let audio = document.createElement('audio');audio.src = res.data;audio.controls = true;document.body.appendChild(audio);}

点击按钮开始读取数据,但是这里要注意,读取过程是异步的,拿到数据后要进行操作,只能等异步读取完成才行,这里采用回调函数的方式,传入拿到数据后的渲染操作,还有第一个参数应该是number类型,input的值是string类型,需要转换类型,否则无法读取到数据

db.js

 // 读取文件getFile = function (id, callback) {const transaction = db.transaction(['FileStore'], 'readonly');const objectStore = transaction.objectStore('FileStore');const re = objectStore.get(id);re.onsuccess = (e) => {console.log(e.target.result)callback(e.target.result);}re.onerror = function (event) {console.error('文件读取失败:', event.target.errorCode);}}

当数据读取成功后执行回调渲染音频数据

删除文件

 file.js

// 删除歌曲
document.getElementById('del').onclick = () => {delFile(Number(index.value));// getAllFile();
}

db.js

  // 删除文件delFile = function (id) {const transaction = db.transaction(['FileStore'], 'readwrite');const objectStore = transaction.objectStore('FileStore');const re = objectStore.delete(id);re.onsuccess = function (event) {console.log('文件删除成功');}}

和读取操作差不多

修改文件

file.js

// 更新歌曲
update.onchange = () => {for (item of update.files) {if (item.type == 'audio/mpeg') {console.log('音频文件');let blob = new Blob([item], { type: 'audio/mpeg' });let reader = new FileReader();reader.readAsDataURL(blob);reader.onload = () => {//读取的过程是异步的// console.log(reader.result);updateFile({id: Number(index.value),name: item.name,size: item.size,type: item.type,data: reader.result})// getAllFile();}}else{alert('请选择音频文件');}}

类似上传,但是要注意,修改要带上id键值, 

db.js

  // 更新文件updateFile = function (file) {const transaction = db.transaction(['FileStore'], 'readwrite');const objectStore = transaction.objectStore('FileStore');const re = objectStore.put(file);re.onsuccess = function (event) {console.log('文件更新成功');}}

查看数据库的表时,可能数据没有更新,可以手动刷新一下

修改值

db.js

  // 更新文件对象值updataVal = function (id,key,val) {const transaction = db.transaction(['FileStore'], 'readwrite');const objectStore = transaction.objectStore('FileStore');// 打开一个移动指针objectStore.openCursor().onsuccess = function (event) {const cursor = event.target.result;if (cursor) {// 指针存在,有数据console.log(cursor);if(cursor.value.id === id){// 匹配数据idlet updateData = cursor.value;// 获取数据对象updateData[key] = val;// 修改对应键的值const re = cursor.update(updateData);// 将新的数据对象替换原数据对象,更新数据re.onsuccess = function (event) {console.log('更新成功',cursor.value);}}else{cursor.continue(); // 指针继续移动}}else{// 没有数据或者指针移出了数据列表console.log('没有更多数据了');}}}updataVal(1,'name','歌曲');

这个逻辑会复杂一些,这里用到了文件指针,它会指向存储对象表,可以像链表一样,移动遍历整个存储对象表,

第一首歌曲的name属性被改成了'歌曲',

渲染对象数据表

为了让这些操作更直观,将渲染对象数据表的id和name属性渲染出来,并在页面载入后,和数据表变化时渲染最新数据

db.js

  // 获取所有文件getAllFile = function () {const transaction = db.transaction(['FileStore'], 'readonly');const objectStore = transaction.objectStore('FileStore');const re = objectStore.getAll();re.onsuccess = (e) => {const res = e.target.resultlet ul = document.createElement('ul');let li = document.createElement('li');li.innerText = "本地存储的歌曲"ul.appendChild(li);for (item of res) {let li = document.createElement('li');li.innerText = item.id + ":" + item.name;ul.appendChild(li);}document.body.appendChild(ul);}}getAllFile();

将所有数据读取,并渲染成列表,可以把前面注释的getAllFile()取消注释

这样就很直观的查看对象数据表的变化

完整代码展示

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" multiple> --><div><label for="file">存储歌曲</label><input type="file" name="" id="file" style="display: none;"><input type="number" name="" value="1" id="index" style="width: 40px;"><button id="bt">获取歌曲</button><button id="del">删除歌曲</button><label for="update">修改歌曲</label><input type="file" name="" id="update" style="display: none;"></div><script src="db.js"></script><script src="file.js"></script>
</body></html>

file.js

const file = document.getElementById('file');
const update = document.getElementById('update');
const index = document.getElementById('index');// 添加歌曲
file.onchange = () => {console.log(file.files);for (item of file.files) {if (item.type == 'audio/mpeg') {console.log('音频文件');let blob = new Blob([item], { type: 'audio/mpeg' });let reader = new FileReader();reader.readAsDataURL(blob);reader.onload = () => {//读取的过程是异步的// console.log(reader.result);addFile({name: item.name,size: item.size,type: item.type,data: reader.result})getAllFile();}}else{alert('请选择音频文件');}// if (item.type == 'image/jpeg') {//   console.log('图片文件');//   let blob = new Blob([item], { type: 'image/jpeg' });//   console.log(blob);//   let url = URL.createObjectURL(blob);//   console.log(url);//   let img = document.createElement('img');//   img.src = url;//   img.width = 200;//   document.body.appendChild(img);// }// if (item.size > 1024 * 1024 * 2) {//   console.log('文件大于2mb');// }}}// 更新歌曲
update.onchange = () => {for (item of update.files) {if (item.type == 'audio/mpeg') {console.log('音频文件');let blob = new Blob([item], { type: 'audio/mpeg' });let reader = new FileReader();reader.readAsDataURL(blob);reader.onload = () => {//读取的过程是异步的// console.log(reader.result);updateFile({id: Number(index.value),name: item.name,size: item.size,type: item.type,data: reader.result})getAllFile();}}else{alert('请选择音频文件');}}
}// 获取歌曲
document.getElementById('bt').onclick = () => {getFile(Number(index.value),getAudio);
};// 删除歌曲
document.getElementById('del').onclick = () => {delFile(Number(index.value));getAllFile();
}const getAudio = (res) => {let span = document.createElement('span');span.innerText = res.name;document.body.appendChild(span);let audio = document.createElement('audio');audio.src = res.data;audio.controls = true;document.body.appendChild(audio);}

db.js


// 浏览器本地数据库
console.log(indexedDB);// window.indexedDB// 使用indexedDB来存储文件。
// 打开数据库
const request = indexedDB.open('FileDatabase', 4);
let addFile;//添加文件的方法
let getFile;//读取文件的方法
let delFile;//删除文件的方法
let updateFile;//更新文件的方法
let updataVal;//更新文件对象值的方法
let getAllFile;//获取所有文件的方法request.onerror = function (event) {console.error('数据库打开失败:', event.target.errorCode);}request.onupgradeneeded = function (event) {const db = event.target.result;// 创建一个存储对象db.createObjectStore('FileStore', { keyPath: 'id', autoIncrement: true });console.log('数据库储存对象(表)创建成功');// // 删除一个存储对象,只能在更新版本时删除// db.deleteObjectStore('FileStore');// console.log('数据库储存对象(表)删除成功');
}request.onsuccess = function (e) {const db = e.target.result;console.log('数据库打开成功', db);// 添加文件addFile = function (file) {// 连接数据库的表,比获取读写权限,默认只读const transaction = db.transaction(['FileStore'], 'readwrite');const objectStore = transaction.objectStore('FileStore');const re = objectStore.add(file);re.onsuccess = function (event) {console.log('文件添加成功');}}// 读取文件getFile = function (id, callback) {const transaction = db.transaction(['FileStore'], 'readonly');const objectStore = transaction.objectStore('FileStore');const re = objectStore.get(id);re.onsuccess = (e) => {console.log(e.target.result)callback(e.target.result);}re.onerror = function (event) {console.error('文件读取失败:', event.target.errorCode);}}// 删除文件delFile = function (id) {const transaction = db.transaction(['FileStore'], 'readwrite');const objectStore = transaction.objectStore('FileStore');const re = objectStore.delete(id);re.onsuccess = function (event) {console.log('文件删除成功');}}// 更新文件updateFile = function (file) {const transaction = db.transaction(['FileStore'], 'readwrite');const objectStore = transaction.objectStore('FileStore');const re = objectStore.put(file);re.onsuccess = function (event) {console.log('文件更新成功');}}// 更新文件对象值updataVal = function (id,key,val) {const transaction = db.transaction(['FileStore'], 'readwrite');const objectStore = transaction.objectStore('FileStore');// 打开一个移动指针objectStore.openCursor().onsuccess = function (event) {const cursor = event.target.result;if (cursor) {// 指针存在,有数据console.log(cursor);if(cursor.value.id === id){// 匹配数据idlet updateData = cursor.value;// 获取数据对象updateData[key] = val;// 修改对应键的值const re = cursor.update(updateData);// 将新的数据对象替换原数据对象,更新数据re.onsuccess = function (event) {console.log('更新成功',cursor.value);}}else{cursor.continue(); // 指针继续移动}}else{// 没有数据或者指针移出了数据列表console.log('没有更多数据了');}}}// 获取所有文件getAllFile = function () {const transaction = db.transaction(['FileStore'], 'readonly');const objectStore = transaction.objectStore('FileStore');const re = objectStore.getAll();re.onsuccess = (e) => {const res = e.target.resultlet ul = document.createElement('ul');let li = document.createElement('li');li.innerText = "本地存储的歌曲"ul.appendChild(li);for (item of res) {let li = document.createElement('li');li.innerText = item.id + ":" + item.name;ul.appendChild(li);}document.body.appendChild(ul);}}getAllFile();// updateTest();
}function updateTest(){updataVal(1,'name','江南.mp3');getAllFile();
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络之奇偶校验码和CRC冗余校验码

今天我们来看看有关于计算机网络的知识——奇偶校验码和CRC冗余校验码&#xff0c;这两种检测编码的方式相信大家在计算机组成原理当中也有所耳闻&#xff0c;所以今天我就来跟大家分享有关他们的知识。 奇偶校验码 奇偶校验码是通过增加冗余位使得码字中1的个数恒为奇数或偶数…

嵌入式项目分享| 终极智能手表,全过程+全开源分享

这是一个非常完整的智能手表开源项目,功能齐全,且资料开源,如果你是:自己平时喜欢diy的工程师,想要提升开发技能的学生,马上要做毕设的大四学生,这个手表很值得一做,别错过了~~ 所有开源的资料以及原文链接见文末。 先来看下这个手表的功能: 首先,是一个可以佩戴的手…

微型导轨:手术机器人的高精度“骨骼”

微型导轨精度高&#xff0c;摩擦系数小&#xff0c;自重轻&#xff0c;结构紧凑&#xff0c;被广泛应用在医疗器械中&#xff0c;尤其是在手术机器人中的应用&#xff0c;通过手术机器人&#xff0c;外科医生可以远离手术台操纵机器人进行手术。可以说&#xff0c;是当之无愧的…

经验分享,在线word转图片

这里分享一个在线word转图片的网站&#xff0c;比较好用 网址&#xff1a;http://www.docpe.com/word/word-to-image.aspx 截图&#xff1a;

Spring Boot如何实现跨域资源共享(CORS)?

&#x1f345; 作者简介&#xff1a;哪吒&#xff0c;CSDN2021博客之星亚军&#x1f3c6;、新星计划导师✌、博客专家&#x1f4aa; &#x1f345; 哪吒多年工作总结&#xff1a;Java学习路线总结&#xff0c;搬砖工逆袭Java架构师 &#x1f345; 技术交流&#xff1a;定期更新…

浔川3样AI产品即将上线!——浔川总社部

浔川3样AI产品即将上线&#xff01; 浔川AI翻译v3.0 即将上线&#xff01; 浔川画板v5.1 即将上线&#xff01; 浔川AI五子棋v1.4 即将上线&#xff01; 整体通告详见&#xff1a;浔川AI五子棋&#xff08;改进&#xff08;完整&#xff09;版1.3&#xff09;——浔川python社…

Java洗鞋预约小程序源码

&#x1f4a5;洗鞋神器来袭&#xff01;轻松预约&#xff0c;让你的鞋子焕然一新&#x1f45f; &#x1f389; 告别洗鞋烦恼&#xff0c;洗鞋预约小程序来啦&#xff01; 你是不是常常为洗鞋而烦恼&#xff1f;手洗太累&#xff0c;送去洗衣店又贵又麻烦。现在&#xff0c;好…

初识Java(二)

初识Java的main方法 1.1 main方法示例 public class world {public static void main(String[] args) {System.out.println("hello,world!");}}通过上述代码&#xff0c;我们可以看到一个完整的Java程序的结构&#xff0c;Java程序的结构由如下三个部分组成&#x…

Day 34:2368. 受限条件下可到达节点的数目

Leetcode 2368. 受限条件下可到达节点的数目 现有一棵由 n 个节点组成的无向树&#xff0c;节点编号从 0 到 n - 1 &#xff0c;共有 n - 1 条边。 给你一个二维整数数组 edges &#xff0c;长度为 n - 1 &#xff0c;其中 edges[i] [ai, bi] 表示树中节点 ai 和 bi 之间存在一…

【广度优先搜索 深度优先搜索 图论】854. 相似度为 K 的字符串

本文涉及知识点 广度优先搜索 深度优先搜索 图论 图论知识汇总 深度优先搜索汇总 CBFS算法 LeetCode 854. 相似度为 K 的字符串 对于某些非负整数 k &#xff0c;如果交换 s1 中两个字母的位置恰好 k 次&#xff0c;能够使结果字符串等于 s2 &#xff0c;则认为字符串 s1 和…

three.js 第十一节 - uv坐标

// ts-nocheck // 引入three.js import * as THREE from three // 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js // 导入tween import * as T…

基于Java微信小程序民宿短租系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f;感兴趣的可以先收藏起来&#xff0c;还…

Linux rpm包管理

rpm用于互联网下载包的打包及安装工具&#xff0c;它包含在某些Linux分发版中。它生成具有.RPM扩展名的文件。RPM是RedHat Package Manager (RedHat软件包管理工具&#xff09;的缩写&#xff0c;类似windows的setup.exe&#xff0c;这一文件格式名称虽然打上了RedHat的标志&am…

【Redis】

Redis 常见面试题 认识 Redis 什么是 Redis&#xff1f; 我们直接看 Redis 官方是怎么介绍自己的。 Redis 官方的介绍原版是英文的&#xff0c;我翻译成了中文后截图的&#xff0c;所以有些文字读起来会比较拗口&#xff0c;没关系&#xff0c;我会把里面比较重要的特性抽出来…

经典游戏案例:仿植物大战僵尸

学习目标&#xff1a;仿植物大战僵尸核心玩法实现 游戏画面 项目结构目录 部分核心代码 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using Random UnityEngine.Random;public enum…

STM32启动流程 和 map文件的作用

一&#xff0c;启动流程 1. 复位/上电 2. 根据 BOOT0/BOOT1 确定程序从哪个存储位置执行 3. 初始化 SP 及 PC 指针 将 0X08000000 位置的栈顶地址存放在 SP 指针中 将 0x08000004 位置存放的向量地址装入 PC 程序计数器 4. 初始化系统时钟 5. 初始化用户堆栈 6. 进入main函数 二…

idea中maven新增的配置文件xx.xml没生效问题

项目场景&#xff1a; 因为公司使用自己的私服下载jar,则没有使用默认的settings.xml文件。而是新增了一个settingsold.xml文件 问题描述 公司项目有用自己的私服,Maven正常去私服下载jar包是没问题的。但是一直是去找的阿里云镜像,到导致阿里云镜像找不到相关的jar包报错!!!…

条码二维码读取设备在医疗设备自助服务的重要性

医疗数字信息化建设的深入推进&#xff0c;医疗设备自助服务系统已成为医疗服务领域的一大趋势&#xff0c;条码二维码读取设备作为自助设备的重要组成部分&#xff0c;通过快速、准确地读取条形码二维码信息&#xff0c;不公提升了医疗服务效率&#xff0c;还为患者提供了更加…

CMN-700(1)CMN-700概述

本章介绍CMN-700&#xff0c;这是用于AMBA5 CHI互连&#xff0c;且可根据需要定制的网格拓扑结构。 1. 关于CMN‐700 CMN‐700是一种可配置扩展的一致性互连网络&#xff0c;旨在满足高端网络和企业计算应用中使用的一致性网络系统的功率、性能和面积(PPA)要求。支持1-256个处…

PHP 界的扛把子 Swoole 异步通信利器

大家好&#xff0c;我是码农先森。 引言 我今天主要介绍的内容是包括但不仅限于 Swoole &#xff0c;也有一部分 Go 语言的内容。 为什么要介绍 Swoole ? 先说一说背景吧&#xff0c;我们项目组之前要为《香港 01》开发一个积分系统的项目&#xff0c;这个系统的主要功能包…