IndexedDB使用

使用场景

  • 具体使用场景:

存储用户浏览记录。

  • 适合的使用场景:
  1. 处于安全性考虑,数据不能存储到服务器端。
  2. 数据为结构性数据或者数据量较大,不适合使用cookies。
  3. 希望数据不随着客户清理缓存而删除。此时我们一定一定要设计好清理浏览器端数据的时机。

相关站点

  1. MDN文档(中英) 访问
  2. IBM develoerWorks(中文) 访问
  3. 这个可能是最权威的了吧,W3C(英文)访问

ps:那么多好的资料了,为什么还写博客?

  1. 做笔记;
  2. 我用的Angular2,语法糖是ES6的啊。

代码段

代码段来自项目,当然是底层的与项目无关。这部分代码大部分是已有的,来自一个已经离开项目的同事,我写了一部分。在此我只是记录下而已。

// 项目使用的是Angular2,这是一个service。有关Angular2的写法我不做说明。
import { Injectable } from '@angular/core';@Injectable()
export class WorkIndexedDBService {// 声明一些属性,name:数据库名,version:数据库版本// name和version发生变化,浏览器就会重新建一个新的indexedDBprivate name: string = 'test-docView';private version: number = 1;private db: any = null;constructor() { }// 打开并创建数据库public open(): Promise<any> {return new Promise<any>((resolve, reject) => {// 打开indexedDBlet req = indexedDB.open(this.name, this.version);// 打开DB成功后的回调req.onsuccess = function(event) {this.db = event.target.result;resolve();}.bind(this);
// 此处说明.bind(this),是为了把当前类的属性和方法传入req.onsuccess的这个function里。即:.bind(this)的this是指本类WorkIndexedDBService// 打开DB失败后的回调req.onerror = reject;// 打开新的数据库时,会回调此函数,改变name和version均会建立新的DB,所以都会发生此回调。req.onupgradeneeded = function(event) {// 如果版本升级要记得删除旧的数据库表再建立新的。this.db = event.target.result;let storeNames = this.db.objectStoreNames;if (storeNames && storeNames.length > 0) {for (let i = 0 ; i < storeNames.length ; i++) {this.db.deleteObjectStore(storeNames[i]);console.log('deleteObjectStore', storeNames[i]);}}// 创建数据库表this.createViewDB();}.bind(this);});}// 关闭数据库public close(): void {this.db.close();}// 删除数据库public deleteDB(): Promise<any> {return new Promise<any>((resolve, reject) => {// 先关闭连接再删this.close();let req = indexedDB.deleteDatabase(this.name);req.onsuccess = function(event) {this.db = null;resolve();}.bind(this);req.onerror = reject;});}// 添加数据// 注意:使用事务来做操作比较快。public insert(storeName: string,data: any): Promise<any> {return new Promise<any>((resolve, reject) => {let transaction = this.db.transaction(storeName, 'readwrite');let store = transaction.objectStore(storeName);let req = store.add(data);req.onsuccess = function(event) {resolve(req.result);};req.onerror = reject;});}// 批量添加数据public batchInsert(storeName: string,data: any[]): Promise<any> {if (!data || data.length === 0) {return Promise.resolve();}let transaction = this.db.transaction(storeName, 'readwrite');let store = transaction.objectStore(storeName);return new Promise<null>((resolve, reject) => {data.forEach(row => store.add(row);});transaction.oncomplete = resolve;transaction.onerror = reject;}).catch((error) => {console.error('添加' + storeName + '表数据失败', error);return Promise.reject(error);});}// 删除数据public workdelete(storeName: string,keyValue: any): Promise<any> {return new Promise<any>((resolve, reject) => {let transaction = this.db.transaction(storeName, 'readwrite');let store = transaction.objectStore(storeName);let req = store.delete(keyValue);req.onsuccess = resolve;req.onerror = reject;});}// 清楚全部数据public clearAllData(): Promise<any> {let storeNameList: Array<string> = new Array<string>();let storeNames = this.db.objectStoreNames;if (storeNames && storeNames.length > 0) {for (let i = 0 ; i < storeNames.length ; i++) {storeNameList.push(storeNames[i]);}}return Promise.all(storeNameList.map((storeName) => {return this.clear(storeName);}));}// 清空数据public clear(storeName: string): Promise<any> {return new Promise<any>((resolve, reject) => {let transaction = this.db.transaction(storeName, 'readwrite');let store = transaction.objectStore(storeName);let req = store.clear();req.onsuccess = resolve;req.onerror = reject;});}// 更新数据public update(storeName: string,data: any): Promise<any> {return new Promise<any>((resolve, reject) => {let transaction = this.db.transaction(storeName, 'readwrite');let store = transaction.objectStore(storeName);let req = store.put(data);req.onsuccess = resolve;req.onerror = reject;});}// 根据Key取得数据public selectByKey(storeName: string,keyValue: any): Promise<any> {return new Promise<any>((resolve, reject) => {let transaction = this.db.transaction(storeName, 'readonly');let store = transaction.objectStore(storeName);let req = store.get(keyValue);req.onsuccess = function() {resolve(req.result);}req.onerror = reject;});}// 根据索引取得数据public selectByIndex(storeName: string,indexName: string,indexValue: any): Promise<any[]> {return new Promise<any[]>((resolve, reject) => {let transaction = this.db.transaction(storeName, 'readonly');let store = transaction.objectStore(storeName);let index = store.index(indexName);let req = index.openCursor(indexValue);let result: any[] = new Array<any>();req.onsuccess = function(event) {let cursor = event.target.result;if (cursor) {result.push(cursor.value);cursor.continue();} else {resolve(result);}}req.onerror = reject;});}// 批量合并数据public batchMerge(storeName: string,data: any[],delFlagColName?: string,delFlagColName2?: string): Promise<any> {if (!data || data.length === 0) {return Promise.resolve();}let transaction = this.db.transaction(storeName, 'readwrite');let store = transaction.objectStore(storeName);return new Promise<null>((resolve, reject) => {data.forEach(row => {let keyPath = store.keyPath;let keyValue;if (typeof keyPath === 'string') {keyValue = row[keyPath];} else {keyValue = new Array();keyPath.forEach(key => {keyValue.push(row[key]);});}store.delete(keyValue);} else {store.put(row);}});transaction.oncomplete = resolve;transaction.onerror = reject;}).catch((error) => {console.error('更新' + storeName + '表数据失败', error);return Promise.reject(error);});}// 数据库初始化处理private createDB(): void {this.createConfigInfo();this.createStoreUserInfo();this.createStoreOrgInfo();this.createStoreUserOrgInfo();}// 创建系统配置表及索引private createConfigInfo(): void {let store = this.db.createObjectStore('ConfigInfo',{keyPath: 'key'});}// 创建用户表及索引private createStoreUserInfo(): void {let store = this.db.createObjectStore('UserInfo',{keyPath: 'userId'});}// 创建组织表及索引private createStoreOrgInfo(): void {let store = this.db.createObjectStore('OrgInfo',{keyPath: 'orgId'});store.createIndex('parentOrgIdIndex',['parentOrgId', 'displayOrder'],{unique: false});}// 创建组织表及索引private createStoreUserOrgInfo(): void {let store = this.db.createObjectStore('UserOrgInfo',// S zhuruifei 2017-08-14 通讯录数据结构变更{keyPath: 'personRoleId'}// E zhuruifei 2017-08-14 通讯录数据结构变更);store.createIndex('orgIdIndex','orgId',{unique: false});}// 创建稿件浏览记录表private createViewDB(): void{let store = this.db.createObjectStore('viewedDoc',{keyPath: 'docId'});store.createIndex('viewedDoc','docId',{unique: true});}// 批量查询稿件浏览信息judgeIfWatched(storeName: string,data: any[]):Promise<any>{if (!data || data.length === 0) {return Promise.resolve();}return Promise.all(data.map((data)=> {return this.selectByKey(storeName,data.docId).then((res)=> {if(res&&res.docId) {data.viewed = "1";}return Promise.resolve();})})).catch((error) => {console.error(error);return Promise.reject(error);});}// 清除30天前的数据cleanViewDB(){this.open().then(()=>{// 通过IDBDatabase得到IDBTransactionlet transaction = this.db.transaction('viewedDoc', 'readonly');// 通过IDBTransaction得到IDBObjectStorelet objectStore = transaction.objectStore("viewedDoc");// 打开游标,遍历customers中所有数据objectStore.openCursor().onsuccess = function(event) {let cursor = event.target.result;if (cursor) {let key = cursor.key;let rowData = cursor.value;var time1 = new Date(rowData.lastViewTime);var time2 = new Date();if(Math.abs(time2.getTime() - time1.getTime())>2592000000){// 清除三十天前的数据this.workdelete('viewedDoc',cursor.key);}cursor.continue();}}.bind(this);})}
}

感谢您看到了这里,这里是结尾。如果对您有帮助,我深感欣慰。自己给自己做广告,不犯法吧?欢迎关注WeChat公众号

**微信公众号: 耐撕程序员

有资源

有想法

有技术贴

随手扫一扫

不吃亏不上当

大家一起天天向上

欢迎扫码关注相互交流**

IndexedDB使用(基本函数封到Angular2的service里)相关推荐

  1. alertdialog报错_在Service里调用AlertDialog

    用常规的方法在AlertDialog的时候,会报错,大意是「can not add window in this view」. 原因是Service是没有界面的,只有Activity才能添加界面. 解 ...

  2. 远古魔力 | 在Windows 10和Azure App Service里跑上世纪的ASP

    ASP(没有.NET) 即 Active Server Pages (动态服务器页面)是一项由微软公司在1996年推出的技术,能够在IIS中运行动态网站.也许许多90后及千禧一代程序员并没有听说过它, ...

  3. 关于 web service 参数传递的序列化反序列化问题

    首先我们要了解 web Service传递的数据只能是序列化的数据,典型的就是xml数据.个人理解就是类似于实体类对象的参数是不需要经过序列化然后传递到webService中,然后在web Servi ...

  4. 浅谈Android四大组件之Service

    一:Service简介 Android开发中,当需要创建在后台运行的程序的时候,就要使用到Service. 1:Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件.其他应用组件 ...

  5. java service注入失败,使用spring向service里面注入dao不成功。

    使用spring向service里面注入dao不成功.求救啊! 本帖最后由 PaperStar 于 2013-12-26 19:29:20 编辑 页面调用action,action调用service, ...

  6. 代码结构中 Dao,Service,Controller,Util,Model 是什么意思,为什么划分?

    欢迎关注方志朋的博客,回复"666"获面试宝典 适合受众:2年以下的初级程序员和0基础的门外汉 内容大纲: 1.为什么需要一个好的代码结构 2.什么样才是一个好的结构 3.每一个分 ...

  7. Android中的service全面总结

    文章出处:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html 1.Service的种类 按运行地点分类: 类别 区别  优点 缺点 ...

  8. Service 与 Thread 的区别

    Service 与 Thread 的区别 很多时候,你可能会问,为什么要用 Service,而不用 Thread 呢,因为用 Thread 是很方便的,比起 Service 也方便多了,下面我详细的来 ...

  9. Java Web学习总结(30)——Service层在MVC框架中的意义和职责

    mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面. mvc模式是web开发中的基础模式,采用的是分层设计, ...

最新文章

  1. POJ 2104 K-th Number(区间第k大数)(平方切割,归并树,划分树)
  2. Linux Mint 13 root登录
  3. 引用可以是void类型吗?
  4. 写代码?程序猿?你不能不懂的八大排序算法的Python实现
  5. NOI数据结构:树套树
  6. 使用.NET Standard 2的Elasticsearch,Kibana和Docker
  7. 惠普HP ProDesk 400 G2 加装BCM94352HMB网卡
  8. CAPM模型的应用--回归模型中的Alpha, r_f
  9. 【第10章】接口与Lambda表达式
  10. 东华理工大学计算机网络期末考试试卷,东华理工大学计算机网络计算题
  11. 程序员更容易生女孩子,是不是真的?
  12. Rancher hosted Kubernetes AKS
  13. 一文让你通俗理解奇异值分解
  14. SlickEdit生成.a或.so后缀的makefile文件
  15. 摇摇棒C语言程序,AT89S52单片机16LED摇摇棒设计(含pcb文件,源程序等)
  16. 由于oracle错误1400而拒绝行,请教各位大神一个在工作中遇到的问题。到现在还没有解决。 - Oracle论坛 - 51CTO技术论坛_中国领先的IT技术社区...
  17. 【010】汉典-纯粹的汉语字典数据库
  18. 社区分享|货拉拉通过JumpServer纳管大规模云上资产
  19. pip 更新国内源以及官方源
  20. mac下使用automator制作Finder复现文件夹路径快捷键

热门文章

  1. 7 个让您需要渐进式 Web 应用程序做项目开发的理由
  2. 在iOS开发中使用FMDB
  3. 数据库ORA-00600 [15160]处理
  4. 一张图片学Python
  5. 使用 Label 类在 XNA 中显示文本,WPXNA(七)
  6. 在线聊天javascript代码
  7. Delphi使用Zlib
  8. 基于用例的工作量估计
  9. Java核心技术卷1心得笔记1---Java程序设计概述
  10. 下拉插件dropload js时间计算(几天前)