zoukankan      html  css  js  c++  java
  • 新建 indexedDB 数据库并插入数据

    一、什么叫数据库

    DB的全名是database,即数据库。

    二、数据库的种类

    数据库有两种类型,分别是关系型数据库和非关系型数据库。

    • 关系型数据库:OracleDB2MicrosoftSQLServer、MicrosoftAccess、MySQL等。
    • 非关系型数据库:NoSql、Cloudant、MongoDb、redis、HBase等。

    关系型数据库的优点:

    1. 能够复杂查询:可以用SQL句子便捷的在一个表及多个表之间做复杂的数据查询。
    2. 事务支持性优秀:能够实现对于安全性要求很高的数据访问。

    非关系型数据库的优点:

    1. 性能好:NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,并且不用通过SQL层的解析,因此性能表现优异。
    2. 可扩展性好:同样也是基于键值对,数据间耦合度低,因此很容易水平扩展。
    • SQL (Structured Query Language) 是一种数据库语言 。
    • 就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。

    IndexedDB 具有以下特点

    (1)键值对储存。 IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。

    (2)异步。 IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。

    (3)支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。

    (4)同源限制 IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。

    (5)储存空间大 IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限。

    (6)支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。

    • 数据库是一系列相关数据的容器。
    • 每个数据库包含若干个对象仓库(object store)。它类似于关系型数据库的表格。
    • 对象仓库保存的是数据记录。每条记录类似于关系型数据库的行,但是只有主键和数据体两部分。
    • 数据库 > 对象仓库 > 数据记录

    操作流程

    1. 打开数据库:  indexedDB.open()

      var version = 1;
      var databaseName = "database";
      var request = window.indexedDB.open(databaseName, version);//这是一个异步操作,但是会立刻返回一个IDBOpenDBRequest对象。方法返回一个IDBRequest对象。这个对象通过三种事件error、success、upgradeneeded处理打开数据库的操作结果。
      var db;
      
      /**
       * 新建数据库与打开数据库是同一个操作。
       * 如果要打开的数据库不存在,则会先新建数据库:
       *         1. 新建数据库时调用 request.onupgradeneeded(因为这时版本从无到有,所以会触发这个事件)
       *         2. 把数据库版本设为 1
       *         3. 此时数据库对象 db = e.target.result;
       * 新建数据库后,就可以打开数据库了,所以继续调用 request.onsuccess
       * */
      request.onupgradeneeded = function(e) {
          db = e.target.result;
          console.log("onupgrageneeded");
          // 通常新建数据库以后,第一件事是新建对象仓库(即新建表),并设置主键
          var objectStore = db.createObjectStore("person", {
              keyPath: "id" //设置主键为 id
          });
      }
      
      /**
       * 如果要打开的数据库存在,则会直接打开该数据库
       * 此时数据库对象 db = request.result;
       * */
      request.onsuccess = function(e) {
          db = request.result;
          console.log("success");
      }
      
      /**
       * 数据库打开错误时调用此回调函数
       * */
      request.onerror = function(e) {
          console.log("error");
      }

    2. 新建数据库:

      新建数据库与打开数据库是同一个操作。如果指定的数据库不存在,就会新建。
      a. 新建对象仓库(即新建表)。
      request.onupgradeneeded = function(e) {
          db = e.target.result;
          console.log("onupgrageneeded");
          // 通常,新建数据库以后,第一件事是新建对象仓库(即新建表),并设置主键
          var objectStore = db.createObjectStore("person", {
              keyPath: "id" //设置主键为 id
          });
      }
      b. 更好的写法是先判断一下,这张表格是否存在,如果不存在再新建。
      request.onupgradeneeded = function(e) {
          db = e.target.result;
          console.log("onupgrageneeded");
          // 通常新建数据库以后,第一件事是新建对象仓库(即新建表),并设置主键
          var objectStore;
          if(!db.objectStoreNames.contains(databaseName)) {//如果这个 对象仓库/表 不存在,就新建
              objectStore = db.createObjectStore("person", {
                  keyPath: "id" //设置主键为 id
              });
          }
      }
      c. 如果数据记录里面没有合适作为主键的属性,可以让 IndexedDB 自动生成主键(设置主键)。
      var objectStore = db.createObjectStore("person", { autoIncrement: true }); //指定主键为一个递增的整数

      d. 新建数据库后可以新建当前数据库的索引,使用索引可以更方便的查询数据。

      /**
       * 新建当前数据库的索引
       * 必须在VersionChange监听函数里调用
       * objectStore.createIndex(indexName, keyPath, objectParameters)
       * indexName:索引名
       * keyPath:主键
       * objectParameters:配置对象(可选)
       * unique:如果设为 true,将不允许重复的值
       * multiEntry:如果设为 true,对于有多个值的主键数组,每个值将在索引里面新建一个条目,否则主键数组对应一个条目。
       * 
       * */
      objectStore.createIndex("name","name",{unique:false});//可以重复
      objectStore.createIndex("age","age",{unique:false});//可以重复
      objectStore.createIndex("email","email",{unique:true});//不能重复

      使用索引查询代码如下:

      useIndex() {
          var db = this.db;
          var objectStore = db.transaction("person","readonly").objectStore("person");
          var index = objectStore.index("name");
          var request = index.get("张三"); //只返回第一个
          // var request = index.getAll("张三");//返回所有的 “张三”
          
          request.onsuccess = function(e){
              var result = e.target.result;
              if(result){
                  console.log("result:",result);
                  console.log("索引查询成功");
              }else{
                  console.log("索引查询失败");
              }
          }
      },
    3. 新增数据:

      新增数据指的是向对象仓库写入数据记录。这需要通过事务完成。
      var obj1 = {id:1,name:"张三",age:24,email:"zhangsan@foxmail.com"};
      var obj2 = {id:2,name:"李四",age:30,email:"lisi@foxmail.com"};
      function addRecord(obj){
          var request = db.transaction(["person"],"readwrite") //写入数据需要新建一个事务。新建时必须指定表格名称和操作模式(“只读”或“读写”)
          .objectStore("person") //新建事务以后,通过IDBTransaction.objectStore(name)方法,拿到 IDBObjectStore 对象
          .add(obj); //再通过表格对象的add()方法,向表格写入一条记录
          request.onsuccess = function(e){
              console.log("数据写入成功");
          }
          request.onerror = function(e){
              console.log("数据写入失败");
          }
      }
      window.onload = function(){
          addRecord(obj1);
          addRecord(obj2);
      }

      注意:不加window.onload 可能存在异步问题,报undefined错误。

      执行过代码后如果对象仓库仍是空,刷新一下即可:

       


    参考文章:

    [1] https://www.shulanxt.com/doc/dbdoc/db-intro

    [2] http://www.ruanyifeng.com/blog/2018/07/indexeddb.html

    [3] https://wangdoc.com/javascript/bom/indexeddb.html

    [4] https://www.bilibili.com/video/BV15J411H7GH

    [5] https://developer.mozilla.org/zh-CN/docs/Web/API/IDBObjectStore

    [6] https://zhuanlan.zhihu.com/p/399223337

  • 相关阅读:
    Two Sum II
    Subarray Sum
    Intersection of Two Arrays
    Reorder List
    Convert Sorted List to Binary Search Tree
    Remove Duplicates from Sorted List II
    Partition List
    Linked List Cycle II
    Sort List
    struts2结果跳转和参数获取
  • 原文地址:https://www.cnblogs.com/sunshine233/p/15638958.html
Copyright © 2011-2022 走看看