彩世界平台-彩世界时时app-彩世界开奖app苹果下载

热门关键词: 彩世界平台,彩世界时时app,彩世界开奖app苹果下载

您的位置:彩世界平台 > 学会党委 > 前端的数据库:IndexedDB入门

前端的数据库:IndexedDB入门

发布时间:2019-11-04 00:11编辑:学会党委浏览(74)

    前端的数据库:IndexedDB入门

    2014/12/27 · 未分类 · IndexedDB

    本文由 伯乐在线 - cucr 翻译,黄利民 校稿。未经许可,禁止转载!
    英文出处:www.codemag.com。欢迎加入翻译组。

    应用程序需要数据。对大多数Web应用程序来说,数据在服务器端组织和管理,客户端通过网络请求获取。随着浏览器变得越来越有能力,因此可选择在浏览器存储和操纵应用程序数据。

    本文向你介绍名为IndexedDB的浏览器端文档数据库。使用lndexedDB,你可以通过惯于在服务器端数据库几乎相同的方式创建、读取、更新和删除大量的记录。请使用本文中可工作的代码版本去体验,完整的源代码可以通过GitHub库找到。

    读到本教程的结尾时,你将熟悉IndexedDB的基本概念以及如何实现一个使用IndexedDB执行完整的CRUD操作的模块化JavaScript应用程序。让我们稍微亲近IndexedDB并开始吧。

    什么是IndexedDB

    一般来说,有两种不同类型的数据库:关系型和文档型(也称为NoSQL或对象)。关系数据库如SQL Server,MySQL,Oracle的数据存储在表中。文档数据库如MongoDB,CouchDB,Redis将数据集作为个体对象存储。IndexedDB是一个文档数据库,它在完全内置于浏览器中的一个沙盒环境中(强制依照(浏览器)同源策略)。图1显示了IndexedDB的数据,展示了数据库的结构

    图片 1

    图1:开发者工具查看一个object store

    全部的IndexedDB API请参考完整文档

    介绍

    IndexedDB就是一个数据库
    其最大的特点是: 使用对象保存数据,而不是使用表来保存数据,同时,它是异步的

    设计典范

    IndexedDB的架构很像在一些流行的服务器端NOSQL数据库实现中的设计典范类型。面向对象数据通过object stores(对象仓库)进行持久化,所有操作基于请求同时在事务范围内执行。事件生命周期使你能够控制数据库的配置,错误通过错误冒泡来使用API管理。

    使用方式

    对象仓库

    object store是IndexedDB数据库的基础。如果你使用过关系数据库,通常可以将object store等价于一个数据库表。Object stores包括一个或多个索引,在store中按照一对键/值操作,这提供一种快速定位数据的方法。

    当你配置一个object store,你必须为store选择一个键。键在store中可以以“in-line”或“out-of-line”的方式存在。in-line键通过在数据对象上引用path来保障它在object store的唯一性。为了说明这一点,想想一个包括电子邮件地址属性Person对象。您可以配置你的store使用in-line键emailAddress,它能保证store(持久化对象中的数据)的唯一性。另外,out-of-line键通过独立于数据的值识别唯一性。在这种情况下,你可以把out-of-line键比作一个整数值,它(整数值)在关系数据库中充当记录的主键。

    图1显示了任务数据保存在任务的object store,它使用in-line键。在这个案例中,键对应于对象的ID值。

    连接数据库

    要使用它必须先打开,通过 indexDB.open(name, version)方法打开一个数据库

    • name : 表示数据要打开的数据库的名称
    • version:为打开数据库的版本号

    基于事务

    不同于一些传统的关系数据库的实现,每一个对数据库操作是在一个事务的上下文中执行的。事务范围一次影响一个或多个object stores,你通过传入一个object store名字的数组到创建事务范围的函数来定义。

    创建事务的第二个参数是事务模式。当请求一个事务时,必须决定是按照只读还是读写模式请求访问。事务是资源密集型的,所以如果你不需要更改data store中的数据,你只需要以只读模式对object stores集合进行请求访问。

    清单2演示了如何使用适当的模式创建一个事务,并在这片文章的 Implementing Database-Specific Code 部分进行了详细讨论。

    indexDB.open()方法的原理

    分为两种情况:
    1. 传入的数据库不存在
    当传入的数据库不存在时,该方法就会创建一个名为name的数据库,并打开它,此时,会先触发upgradeneeded事件;调用该函数会返回一个IDBRequest对象,可以在该对象上添加onsuccess事件onerror事件
    注意:当打开一个不存在的数据库时会触发upgradeneeded事件,这是触发该事件的一种途径,为什么会触发该事件呢?该事件有什么作用?留个疑问在这儿,等会解答。

    2. 传入的数据库存在
    这里分为两种情况:

    • 当传入的数据库存在,且version版本号与将要打开的数据库版本号也相同
      则直接打开该数据库,如果成功,则会触发onsuccess事件,失败则触发onerror事件
      注意:这里并不会触发upgradeneeded事件,为什么?留个疑问

    • 当传入的数据库存在,但是传入的version版本号高于将要打开的数据库的版本号
      则直接打开该数据库,同时触发upgradeneeded事件,然后再触发onsuccess事件onerror事件,这里也触发了onupdateneeded事件

    基于请求

    直到这里,有一个反复出现的主题,您可能已经注意到。对数据库的每次操作,描述为通过一个请求打开数据库,访问一个object store,再继续。IndexedDB API天生是基于请求的,这也是API异步本性指示。对于你在数据库执行的每次操作,你必须首先为这个操作创建一个请求。当请求完成,你可以响应由请求结果产生的事件和错误。

    本文实现的代码,演示了如何使用请求打开数据库,创建一个事务,读取object store的内容,写入object store,清空object store。

    upgradeneeded事件

    触发该事件的条件:当打开的数据库不存在,或者传入的数据库版本version高于当前版本,则会触发该事件

    upgradeneeded事件的作用:当打开了一个数据库之后,需要开辟一个名为:对象存储空间 的玩意(可以理解为数据就是存放在这个空间里面,一个数据库可以创建多个对象存储空间),而 对象存储空间 只能在upgradeneeded事件的处理函数中创建

    使用时,注意以下两种情况:

    1. 当我们第一次打开创建数据库时,会触发upgradeneeded事件,我们就需要在其中创建对象存储空间

    2. 当我们对数据库版本进行更新时,也会触发该事件,这时可以在此创建新的对象存储空间,原来的对象存储空间仍然存在

    注意:如果需要对对象存储空间进行修改,那么只能先将存储在它里面的数据读取出来,再将其删除,然后使用新的选项去创建它,再写入原来的数据

    打开数据库并创建对象存储空间的代码:

    // 对于该API,各浏览器还未同一,所以需要对一些接口添加前缀
    window.indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB;
    window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE: "readwrite"};
    window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
    window.IDBCursor = window.IDBCursor || window.webkitIDBTransaction;
    
    // 判断浏览器是否支持IndexedDB
    if (!window.indexedDB) {
    window.alert("Your browser doesn't support a stable version of IndexedDB.")
    }
    
    var request , db;
    // 打开或创建 名为dbName的数据库
    request = window.indexedDB.open('dbName', 2)
    request.onsuccess = function (event) {
       db = event.target.result;
    }
    
    request.onerror = function (event) {
       console.log('错误代码: ' + event.target.errorCode);
    }
    
    request.onupgradeneeded = function(event) {
      db = event.target.result;  // 
      // 创建一个   对象存储空间,名为customers
      var objectStore = db.createObjectStore('customers', {keyPath: 'ssn'});
      // 对于某些数据,可以为一个对象存储空间指定多个键。比如,若要通过用户ID 和用户名 两种方式来保存用户资料,就需要通过两个键来存取记录
      // 因此可以使用createIndex,名字是有可能重复的,所以其unique 设置为 false ;第一个name是索引的名字,该名字是索引的名字,第二个name是索引的属性的名字,该名字要与对象中的属性相同
      objectStore.createIndex('name', 'name', { unique: false});
    
      // 创建一个email的索引,该email是独特的,所以 unique 设置为 true
      objectStore.createIndex('email', 'email', { unique: true});
    }
    

    打开数据库的请求生命周期

    IndexedDB使用事件生命周期管理数据库的打开和配置操作。图2演示了一个打开的请求在一定的环境下产生upgrade need事件。

    图片 2

    图2:IndexedDB打开请求的生命周期

    所有与数据库的交互开始于一个打开的请求。试图打开数据库时,您必须传递一个被请求数据库的版本号的整数值。在打开请求时,浏览器对比你传入的用于打开请求的版本号与实际数据库的版本号。如果所请求的版本号高于浏览器中当前的版本号(或者现在没有存在的数据库),upgrade needed事件触发。在uprade need事件期间,你有机会通过添加或移除stores,键和索引来操纵object stores。

    如果所请求的数据库版本号和浏览器的当前版本号一致,或者升级过程完成,一个打开的数据库将返回给调用者。

    存储数据

    存储数据有两种方法:add()方法put()方法

    这两种方法的区别主要体现在:当要添加数据的对象存储空间中已经存在有相同键的数据时,使用add()方法添加数据会报错误,而put()方法则会对现有数据进行更新,所以add()方法一般用于初始化数据,而put()方法用于更新数据

    代码如下:

    // customerData 为要存储的数据
    const customerData = [{ ssn: '444-44-4444', name: 'AAA', age: 35, email: '[AAA@company.com](mailto:AAA@company.com)'},{ ssn: '666-66-6666', name: 'CCC', age: 35, email: '[CCC@company.com](mailto:CCC@company.com)'},{ ssn: '777-77-7777', name: 'DDD', age: 32, email: '[DDD@home.org](mailto:DDD@home.org)'},{ ssn: '555-55-5555', name: 'BBB', age: 32, email: '[BBB@home.org](mailto:BBB@home.org)'},
    ];
    
    // 创建一个事务,该事务将要对名为“customers”的对象存储空间进行 read和write 操作,并返回事务索引
    let transaction = db.transaction('customers', 'readwrite'); 
    
    // 取得索引后,使用objectStore()方法并传入存储空间的名称,就可以访问特定的存储空间,这两步是必须的
    let store = transaction.objectStore('customers'); 
    
    // 添加数据到数据库中
    for (var i in customerData) {
      // 返回的req也是一个对象,可以为其添加onsuccess和onerror事件,来检测数据是否添加成功
      let req = store.put(customerData[i]);   // 往一个存储空间中添加数据
    
    }
    // 判断事务整个操作完成
    transaction.oncomplete = function(event) {
      console.log(event.target);
      alert('存储数据完成');
    };
    }
    

    如上就将数据存储到数据库dbNames的customers对象存储空间中

    上面代码中提到了 [事务],这里先记住:凡是涉及到对数据库的读写删除操作,都需要通过 [事务] 来完成

    错误冒泡

    当然,有时候,请求可能不会按预期完成。IndexedDB API通过错误冒泡功能来帮助跟踪和管理错误。如果一个特定的请求遇到错误,你可以尝试在请求对象上处理错误,或者你可以允许错误通过调用栈冒泡向上传递。这个冒泡天性,使得你不需要为每个请求实现特定错误处理操作,而是可以选择只在一个更高级别上添加错误处理,它给你一个机会,保持你的错误处理代码简洁。本文中实现的例子,是在一个高级别处理错误,以便更细粒度操作产生的任何错误冒泡到通用的错误处理逻辑。

    事务和查询操作数据

    最简单的创建事务的方式是:
    var transaction = db.transaction(); // db就是前面的数据库对象
    这种方式创建的事务,只能读取数据库中保存的所有对象

    一般用法是:
    var transaction = db.transaction('customes', 'readwrite');
    表示只加载customers对象存储空间中的数据,并且是以可读可写的方式加载

    如果不传第二个参数,则表示只可访问,不可修改;

    这里返回的transaction是事务的索引

    然后使用objectStore()方法并传入对象存储空间的名称,就可以访问特定的存储空间了;

    如下:

    let transaction = db.transaction('customers', 'readwrite'); 
    let store = transaction.objectStore('customers'); 
    

    取得了上面的store后,我们可以使用如下方法对数据进行操作:

    • add()和put()方法:用于存储数据
      let req = store.add(data);
    • get(key)方法:获取键为key的对象
      let req = store.get(key);
    • delete(key)方法:删除键为key的对象
      let req = store.delete(key);
    • clear()方法:清空对象存储空间中的所有对象
      let req = store.clear();
      使用上述方法会返回一个对象,通过对其添加onsuccess和onerror事件,可以检测操作是否成功

    注意:通过oncomplete事件对象,访问不到get()请求返回的任何数据,必须在响应请求的onsuccess事件处理程序中才能访问到数据

    浏览器支持

    也许在开发Web应用程序最重要的问题是:“浏览器是否支持我想要做的?“尽管浏览器对IndexedDB的支持在继续增长,采用率并不是我们所希望的那样普遍。图3显示了caniuse.com网站的报告,支持IndexedDB的为66%多一点点。最新版本的火狐,Chrome,Opera,Safar,iOS Safari,和Android完全支持IndexedDB,Internet Explorer和黑莓部分支持。虽然这个列表的支持者是令人鼓舞的,但它没有告诉整个故事。

    图片 3

    图3:浏览器对IndexedDB的支持,来自caniuse.com

    只有非常新版本的Safari和iOS Safari 支持IndexedDB。据caniuse.com显示,这只占大约0.01%的全球浏览器使用。IndexedDB不是一个你认为能够理所当然得到支持的现代Web API,但是你将很快会这样认为。

    使用游标查询数据

    使用事务可以直接通过 已知的键检索单个对象。而在需要检索多个对象时,则需要在事务内创建游标。

    游标并不会提前收集结果,游标先指向结果中的第一项,在接到查找下一项的指令时,才会指向下一项

    如下:

    let transaction = db.transaction('customers', 'readwrite'),
    let store = transaction.objectStore('customers'),
    let request = store.openCursor(null) ; // 这里创建游标
    request.onsuccess = function (event) {
      // event.target.result 中保存的是在存储空间中查询到的对象
      // event.target.result 中有几个属性值,可以了解到查询到的对象中的细节,
      // key: 当前访问的对象的键
      // value:当前访问的实际对象
      // primaryKey: 游标使用的键
      // direction:数值,表示游标移动的方向
      let cursor = event.target.result;
      let value, updateRequest, deleteRequest;
    
      // 这里必须要检查游标中是否有数据
      if (cursor) {
        if (cursor.key === '555-55-5555') {
          value = cursor.value;   // 获取到实际的访问对象
          value.name = 'hexon';   // 修改对象的name属性
          // 调用update()方法可以用指定的对象,更新对象的value
          updateRequest = cursor.update(value);     
          updateRequest.onsuccess = function() {
              // 处理成功
           }
        }
        cursor.continue() ;  // 移动到下一项,会触发下一次请求,同时成功则触发request.onsuccess
      }
    }
    

    上面例子中,可以使用cursor.delete()方法删除当前项

    另一种选择

    浏览器支持本地数据库并不是从IndexedDB才开始实现,它是在WebSQL实现之后的一种新方法。类似IndexedDB,WebSQL是一个客户端数据库,但它作为一个关系数据库的实现,使用结构化查询语言(SQL)与数据库通信。WebSQL的历史充满了曲折,但底线是没有主流的浏览器厂商对WebSQL继续支持。

    如果WebSQL实际上是一个废弃的技术,为什么还要提它呢?有趣的是,WebSQL在浏览器里得到稳固的支持。Chrome, Safari, iOS Safari, and Android 浏览器都支持。另外,并不是这些浏览器的最新版本才提供支持,许多这些最新最好的浏览器之前的版本也可以支持。有趣的是,如果你为WebSQL添加支持来支持IndexedDB,你突然发现,许多浏览器厂商和版本成为支持浏览器内置数据库的某种化身。

    因此,如果您的应用程序真正需要一个客户端数据库,你想要达到的最高级别的采用可能,当IndexedDB不可用时,也许您的应用程序可能看起来需要选择使用WebSQL来支持客户端数据架构。虽然文档数据库和关系数据库管理数据有鲜明的差别,但只要你有正确的抽象,就可以使用本地数据库构建一个应用程序。

    键范围

    游标也可以接受一个键,也就是通过键来设定游标查找的范围;
    代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>WebStorage DEMO</title>
    </head>
    <body>
    <div class="networkStatus">
    <button class="clear">清空数据</button>
    <button class="add">添加数据</button>
    <button class="query">查询数据</button>
    <button class="delete">删除数据</button>
    <button class="cursor">使用游标查询</button>
    <button class="keyRange">使用keyrange查询</button>
    <button class="index">使用index</button>
    </div>

    <script>
    let network = document.querySelector('.networkStatus'),
    addBtn = document.querySelector('.add'),
    queryBtn = document.querySelector('.query'),
    deleteBtn = document.querySelector('.delete'),
    cursorBtn = document.querySelector('.cursor'),
    clearBtn = document.querySelector('.clear'),
    keyRange = document.querySelector('.keyRange'),
    indexBtn = document.querySelector('.index')
    ;

    // 判断网路是否在线
    // if (navigator.onLine) {
    // network.innerText = "网络在线";
    // } else {
    // network.innerText = "网络掉线";
    // }

    // // 监控网络状态的事件:online 和 offline, 这两个事件在window对象上
    // window.addEventListener('online', () => {
    // network.innerText = "网络在线";
    // });

    // window.addEventListener('offline', () => {
    // network.innerText = "网络掉线";
    // });

    //--------cookie的使用---------------
    let CookieUtil = {
    get: (name) => {
    let cookieName = encodeURIComponent(name) + "=",
    cookieStart = document.cookie.indexOf(cookieName),
    cookieValue = null;

      if (cookieStart > -1) {
        let cookieEnd = document.cookie.indexOf(';', cookieStart);
        if (cookieEnd === -1) {
          cookieEnd = document.cookie.length;
        }
        cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
      }
    
      return cookieValue;
    },
    set: function (name, value, expires, path, domain, secure) {
      let cookieText = encodeURIComponent(name) + '=' +
                       encodeURIComponent(value);
    
      if (expires instanceof Date) {
        cookieText += '; expires=' + expires.toGMTString();
      }
    
      if (path) {
        cookieText += '; path=' + path;
      }
    
      if (domain) {
        cookieText += '; domain=' + domain;
      }
    
      if (secure) {
        cookieText += '; secure';
      }
    
      document.cookie = cookieText;
    },
    
    // 删除cookie, 并没有直接的删除cookie的方法,这里通过重新设置cookie名称,来对cookie进行替换
    // 同时 将过期时间expires设置为过去的时间,
    unset: function(name, path, domain, secure) {
      this.set(name, '', new Date(0), path, domain, secure);
    }
    

    }

    CookieUtil.set('name', 'hexon');
    CookieUtil.set('book', 'Profession Javascript');

    // 读取cookie的值
    // console.log(CookieUtil.get('name'));
    // console.log(CookieUtil.get('book'));

    // 删除cookie
    CookieUtil.unset('name');
    CookieUtil.unset('book');

    // 设置cookie, 包括它的路径、域、失效日期
    CookieUtil.set('name', 'Hexon', 'books/projs/', 'www.wrox.com', new Date('January 1, 2017'));

    // 删除刚刚设置的cookie
    CookieUtil.unset('name', 'books/projs/', 'www.www.wrox.com');

    // 设置安全的cookie
    CookieUtil.unset('name', 'hexon', null, null, null, null, true)

    // --- IndexedDB 数据库的使用
    var request = window.indexedDB.open('dbName', 2)
    var db;
    const dbName = 'the_name';
    // 创建一个数据
    const customerData = [
    { ssn: '444-44-4444', name: 'AAA', age: 35, email: 'AAA@company.com'},
    { ssn: '666-66-6666', name: 'CCC', age: 35, email: 'CCC@company.com'},
    { ssn: '777-77-7777', name: 'DDD', age: 32, email: 'DDD@home.org'},
    { ssn: '555-55-5555', name: 'BBB', age: 32, email: 'BBB@home.org'},

    ];

    window.indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB;
    window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE: "readwrite"};
    window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
    window.IDBCursor = window.IDBCursor || window.webkitIDBTransaction;

    if (!window.indexedDB) {
    window.alert("Your browser doesn't support a stable version of IndexedDB.")
    }

    // 3 是建立的数据库版本,如果名为MyTestDatabase的数据库不存在,就会创造该数据库,然后 onupgradeneeded 事件会被触发;
    // 如果数据库存在,但是对版本升级了,也会触发onupgradeneeded事件,
    // 注意:版本号是一个 unsigned long long 类型的值,因此不要使用float,否则会将其转换为其最接近的整数

    // 生成处理程序
    request.onerror = function (event) {
    // do Something
    alert('Database error: ' + event.target.errorCode);
    };

    request.onsuccess = function (event) {
    // do Something
    console.log('创建数据库成功');
    db = event.target.result; // 创建成功后,e.target.result 中存储的是IDBDatabase对象的实例
    }

    // 当创建一个新的数据库 或者 更新已存在数据库的版本, onupgradeneeded事件将会被触发,新的对象存储在event.target.result中。
    // 在该处理程序中,数据库已经具有先前版本的对象存储,因此不必再次创建这些对象存储,只需要创建任何我们需要的对象存储,或者
    // 从先前版本中删除不在需要的对象存储。如果需要更改当前对象存储,则必须先删除旧的对象存储,然后在使用新的选项创建。
    // 删除旧的对象存储,在其上的信息都会被删除;
    // 注意:该事件是唯一一个能够对数据库进行操作的地方,在该事件里面,你对对象存储进行删除、修改或移除索引
    request.onupgradeneeded = function(event) {
    console.log('onupgradeneeded');
    var db = event.target.result;

    // 创建一个   对象存储空间,名为customers
    var objectStore = db.createObjectStore('customers', {keyPath: 'ssn'});
    // 对于某些数据,可以为一个对象存储空间指定多个键。比如,若要通过用户ID 和用户名 两种方式来保存用户资料,就需要通过两个键来存取记录
    // 因此可以使用createIndex,名字是有可能重复的,所以其unique 设置为 false ;第一个name是索引的名字,该名字是索引的名字,第二个name是索引的属性的名字,该名字要与对象中的属性相同
    objectStore.createIndex('name', 'name', { unique: false});
    
    // // 创建一个email的索引,该email是独特的,所以 unique 设置为 true
    objectStore.createIndex('email', 'email', { unique: true});
    

    }

    function save(data) {
    /// 对于数据库的对象存储空间中数据的读取或修改数据,都要通过事物来组织所有操作
    // 最简单的创建事物的方法是:var transaction = db.transaction();
    let transaction = db.transaction('customers', 'readwrite'); // 创建一个事务,并定义该事务的操作为 “readwrite” ,并返回其索引
    let store = transaction.objectStore('customers'); // 取得索引后,使用objectStore()方法并传入存储空间的名称,就可以访问特定的存储空间

    for (var i in customerData) {
      let req = store.put(customerData[i]);   // 往一个存储空间中添加数据
    }
    
    transaction.oncomplete = function(event) {
      console.log(event.target);
      alert('存储数据完成');
    };
    
    transaction.onsuccess = function(event ) {
      console.log('onsuccess 事件');
    }
    

    }

    function clear() {
    // body...
    let transaction = db.transaction('customers', 'readwrite');
    let store = transaction.objectStore('customers').clear();
    store.onerror = function(event) {
    console.log('清空数据失败');
    }
    store.onsuccess = function(event) {
    console.log('清空数据成功');
    }
    }

    // 使用事务 直接通过已知的键索引 单个对象 (只能索引单个对象)
    function getData() {
    let transaction = db.transaction('customers', 'readwrite'); // 创建一个事物, 并定义该事务的操作为 "readonly"
    let store = transaction.objectStore('customers').get('444-44-4444'); // 使用get() 可以取得值

    store.onerror = function (event) {
      alert('did not get the object');
    }
    
    store.onsuccess = function (event) {
      var result = event.target.result;
      console.log(result);
      alert('获取数据完成! 年龄是: ' + result.age);
    }
    

    }

    function deleteData() {
    let transaction = db.transaction('customers', 'readwrite');
    let store = transaction.objectStore('customers');
    store.delete('444-44-4444');
    alert('s删除数据完成');
    }

    // 在事务内创建游标查询 可以索引 多个对象(注意: 是多个对象)
    // 游标不提前手机结果
    function cursorQuery() {
    let transaction = db.transaction('customers', 'readwrite'),
    store = transaction.objectStore('customers'),
    request = store.openCursor(null) ; // 这里创建游标

    request.onsuccess = function (event) {
    
      // event.target.result 中保存的是在存储空间中查询到的对象
      // event.target.result 中有几个属性值,可以了解到查询到的对象中的细节,
      // key: 当前访问的对象的键
      // value:当前访问的实际对象
      // primaryKey: 游标使用的键
      // direction:数值,表示游标移动的方向
    
      let cursor = event.target.result;
      let value, updateRequest, deleteRequest;
      if (cursor) {
      //   if (cursor.key === '555-55-5555') {
      //     value = cursor.value;   // 获取到实际的访问对象
      //     value.name = 'hexon';   // 修改对象的name属性
    
      //     updateRequest = cursor.update(value);      // 调用update()方法可以用指定的对象,更新对象的value
      //     updateRequest.onsuccess = function() {
      //       // 处理成功
      //     }
      //     updateRequest.onerror = function() {
      //       // 处理失败
      //     }
    
    
      //     // 使用游标删除当前项
      //     // deleteRequest = cursor.delete();
      //     // deleteRequest.onsuccess = function() {
      //     //   // 删除成功处理
      //     // }
      //     // deleteRequest.onerror = function() {
      //     //   // 删除失败处理
      //     // }
    
    
      //   }
      //   console.log(event.target.result);
      // }
      console.log(cursor.value);
      cursor.continue();      // 移动到下一项,
      }
      request.onerror = function(event) {
        console.log('游标查询创建失败')
      }
    }
    

    }

    // 使用keyrange查询
    function keyRangeQuery() {
    let transaction = db.transaction('customers', 'readwrite')
    let store = transaction.objectStore('customers');
    // 使用bound()方法 定义键范围
    let range = IDBKeyRange.bound('555-55-5555', '777-77-7777', true, false);
    // 将键传入游标创建
    let request = store.openCursor(range);

    request.onsuccess = function(event) {
      let cursor = event.target.result;
      if (cursor) {
        console.log('游标查询到的值' + JSON.stringify(cursor.value));
        cursor.continue()     // 移动到下一项
      }
    
    }
    
    request.onerror = function(event) {
      console.log("使用游标 + keyrange 查询失败")
    }
    

    }

    // 使用索引
    function useIndex() {
    let store = db.transaction('customers').objectStore('customers'),
    index = store.index('name');
    request = index.openCursor();
    request.onsuccess = function (event) {
    let cursor = event.target.result;
    if (cursor) {
    console.log(cursor);
    cursor.continue();
    }
    }
    }

    addBtn.addEventListener('click', function(e) {
    save();
    }, false);

    deleteBtn.addEventListener('click', function(e) {
    deleteData();
    }, false);

    queryBtn.addEventListener('click', function(e) {
    getData();
    }, false);

    cursorBtn.addEventListener('click', function(e) {
    cursorQuery();
    }, false);

    clearBtn.addEventListener('click', function(e) {
    clear();
    }, false);

    keyRange.addEventListener('click', function(e) {
    keyRangeQuery();
    }),

    indexBtn.addEventListener('click', function(e) {
    useIndex();
    })

    </script>

    </body>
    </html>

    本文由彩世界平台发布于学会党委,转载请注明出处:前端的数据库:IndexedDB入门

    关键词:

上一篇:没有了

下一篇:没有了