• 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对象下的一个属性,

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

    打开数据库

    1. const request = indexedDB.open(name, version);
    2. name —— 字符串,即数据库名称。
    3. version —— 一个正整数版本,默认为 1
    4. 返回 openRequest 对象

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

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

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

    1. // 浏览器本地数据库
    2. console.log(indexedDB);// window.indexedDB
    3. // 打开数据库
    4. const request = indexedDB.open('myDatabase', 1);
    5. request.onerror = function(event) {
    6. console.error('数据库打开报错');
    7. }
    8. request.onupgradeneeded = function(event) {
    9. const db = event.target.result;
    10. console.log('数据库需要升级');
    11. // 创建一个对象存储空间
    12. }
    13. request.onsuccess = function(event) {
    14. const db = event.target.result;
    15. console.log('数据库打开成功');
    16. }

     

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

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

    新建一个对象存储表

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

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

    1. // 打开数据库
    2. const request = indexedDB.open('myDatabase', 2);
    3. request.onupgradeneeded = function(event) {
    4. const db = event.target.result;
    5. console.log('数据库需要升级');
    6. // 创建一个对象存储空间
    7. db.createObjectStore('imgStore', { keyPath: 'id', autoIncrement: true });
    8. console.log('对象存储表创建成功');
    9. }
    10. request.onsuccess = function(event) {
    11. const db = event.target.result;
    12. console.log('数据库打开成功');
    13. }

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

    添加和读取数据

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

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

    1. request.onsuccess = function(event) {
    2. const db = event.target.result;
    3. console.log('数据库打开成功');
    4. // 连接数据库的表,比获取读写权限,默认只读
    5. const transaction = db.transaction(['imgStore'], 'readwrite');
    6. const objectStore = transaction.objectStore('imgStore');
    7. // 添加数据
    8. const re = objectStore.add({
    9. name: 'test',
    10. content:'测试数据'
    11. });
    12. re.onsuccess = function (event) {
    13. console.log('文件添加成功');
    14. }
    15. }

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

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

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

    1. request.onsuccess = function(event) {
    2. const db = event.target.result;
    3. console.log('数据库打开成功');
    4. // 连接数据库的表,比获取读写权限,默认只读
    5. const transaction = db.transaction(['imgStore'], 'readwrite');
    6. const objectStore = transaction.objectStore('imgStore');
    7. // // 添加数据
    8. // const re = objectStore.add({
    9. // name: 'test',
    10. // content:'测试数据'
    11. // });
    12. // re.onsuccess = function (event) {
    13. // console.log('文件添加成功');
    14. // }
    15. // 读取数据
    16. const re2 = objectStore.get(1);
    17. re2.onsuccess = function (event) {
    18. console.log(re2.result);
    19. }
    20. }

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

    示例:存储一张图片

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

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

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

    1. let addFile;
    2. request.onsuccess = function (event) {
    3. const db = event.target.result;
    4. console.log('数据库打开成功');
    5. addFile = function (file) {
    6. // 连接数据库的表,比获取读写权限,默认只读
    7. const transaction = db.transaction(['imgStore'], 'readwrite');
    8. const objectStore = transaction.objectStore('imgStore');
    9. const re = objectStore.add(file)
    10. re.onsuccess = function (event) {
    11. console.log('文件添加成功');
    12. }
    13. }
    14. }
    15. const file = document.getElementById('file');
    16. file.addEventListener('change', (event) => {
    17. const file = event.target.files[0];
    18. if (file.type == 'image/jpeg') { // 如果文件是图片
    19. let blob = new Blob([file], { type: 'image/jpeg' });
    20. let reader = new FileReader();
    21. reader.readAsDataURL(blob);
    22. reader.onload = function (event) {
    23. let base64 = event.target.result;
    24. console.log(base64);
    25. addFile({
    26. name: file.name,
    27. data: base64
    28. })
    29. }
    30. }
    31. })

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

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

    1. request.onsuccess = function (event) {
    2. const db = event.target.result;
    3. console.log('数据库打开成功');
    4. let getFile = function(){
    5. // 连接数据库的表
    6. const transaction = db.transaction(['imgStore'], 'readonly');
    7. const objectStore = transaction.objectStore('imgStore');
    8. // 获取数据
    9. const re = objectStore.get(1);
    10. re.onsuccess = function (event) {
    11. console.log(re.result);
    12. let img = new Image();
    13. img.src = re.result.data;
    14. img.width=800;
    15. document.body.appendChild(img);
    16. }
    17. }
    18. getFile()
    19. }

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

    完整代码展示

    index.html

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <title>本地数据库title>
    7. head>
    8. <body>
    9. <input type="file" name="" id="file">
    10. body>
    11. <script src="index.js">script>
    12. html>

    index.js 

    1. // 浏览器本地数据库
    2. console.log(indexedDB);// window.indexedDB
    3. let addFile;//添加文件的方法
    4. // 打开数据库
    5. const request = indexedDB.open('myDatabase', 2);
    6. request.onerror = function (event) {
    7. console.error('数据库打开报错');
    8. }
    9. request.onupgradeneeded = function (event) {
    10. const db = event.target.result;
    11. console.log('数据库需要升级');
    12. // 创建一个对象存储空间
    13. db.createObjectStore('imgStore', { keyPath: 'id', autoIncrement: true });
    14. console.log('对象存储表创建成功');
    15. }
    16. request.onsuccess = function (event) {
    17. const db = event.target.result;
    18. console.log('数据库打开成功');
    19. // // 连接数据库的表,获取读写权限,默认只读
    20. // const transaction = db.transaction(['imgStore'], 'readwrite');
    21. // const objectStore = transaction.objectStore('imgStore');
    22. // // 添加数据
    23. // const re = objectStore.add({
    24. // name: 'test',
    25. // content:'测试数据'
    26. // });
    27. // re.onsuccess = function (event) {
    28. // console.log('文件添加成功');
    29. // }
    30. // 读取数据
    31. // const re2 = objectStore.get(1);
    32. // re2.onsuccess = function (event) {
    33. // console.log(re2.result);
    34. // }
    35. addFile = function (file) {
    36. // 连接数据库的表,获取读写权限,默认只读
    37. const transaction = db.transaction(['imgStore'], 'readwrite');
    38. const objectStore = transaction.objectStore('imgStore');
    39. const re = objectStore.add(file)
    40. re.onsuccess = function (event) {
    41. console.log('文件添加成功');
    42. }
    43. }
    44. let getFile = function(){
    45. // 连接数据库的表
    46. const transaction = db.transaction(['imgStore'], 'readonly');
    47. const objectStore = transaction.objectStore('imgStore');
    48. // 获取数据
    49. const re = objectStore.get(1);
    50. re.onsuccess = function (event) {
    51. console.log(re.result);
    52. let img = new Image();
    53. img.src = re.result.data;
    54. img.width=800;
    55. document.body.appendChild(img);
    56. }
    57. }
    58. getFile()
    59. }
    60. const file = document.getElementById('file');
    61. file.addEventListener('change', (event) => {
    62. const file = event.target.files[0];
    63. if (file.type == 'image/jpeg') { // 如果文件是图片
    64. let blob = new Blob([file], { type: 'image/jpeg' });
    65. let reader = new FileReader();
    66. reader.readAsDataURL(blob);
    67. reader.onload = function (event) {
    68. let base64 = event.target.result;
    69. console.log(base64);
    70. addFile({
    71. name: file.name,
    72. data: base64
    73. })
    74. }
    75. }
    76. })

  • 相关阅读:
    elementui el-table表格自动循环滚动【超详细图解】
    学过单片机的都知道,节电器到底能不能省电
    hdlbits系列verilog解答(7458芯片)-10
    regexp_split_to_table,regexp_split_to_array,array,unnest 使用
    初探JVM
    2个按键加减操作
    xxl-job任务调度2.0.2升级到2.3.0版本,执行器改造过程中经验总结
    seurat dotplot lengend text ptsize
    计算机毕业设计Java校园旺角超市外卖平台(源码+系统+mysql数据库+Lw文档)
    【FPGA】Verilog:计数器 | 异步计数器 | 同步计数器 | 2位二进制计数器的实现 | 4位十进制计数器的实现
  • 原文地址:https://blog.csdn.net/I_am_shy/article/details/139881647