HTML5:离线存储(缓存机制)-IndexDB
https://www.w3.org/TR/IndexedDB/
..
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="jquery-1.12.3.min.js"></script> <script type="text/javascript"> window.indexedDB=window.indexedDB||window.webkitindexedDB||window.mozindexedDB||window.msindexedDB; var DBdescribe={ name:"PersonList133", version:7, db:null }; var tableName="Table01"; openDB(DBdescribe,tableName); function openDB(DBdescribe,tb){ var version = DBdescribe.version || 1; // //打开数据库,存在就打开,不存在新建 var request = indexedDB.open(DBdescribe.name,version); request.onerror = function(e){ console.log(e.currentTarget.error.message); }; //新的数据库创建/老数据库版本设定或者修改 /* 事件command-->request(e)-->goal 1,兼容得到indexDB,indexDB-open->db 2,在版本设定、或者升级||DB成功打开||失败中command事件中的事件参数e得到db 3,DB中创建表(对象存储)(设置是否自增 主键),得到表 table db.createObjectStore 4,表中创建索引(字段:是否唯一) transaction.objectStore在db中创建表 */ request.onupgradeneeded = function(e){ DBdescribe.db=e.target.result; if(!DBdescribe.db.objectStoreNames.contains(tb)){ //db创建table var table= DBdescribe.db.createObjectStore(tb,{keyPath: 'primarykeyid',autoIncrement: true}); //table创建索引(列) table.createIndex('nameIndex','name'); //,{unique:false} table.createIndex('telIndex','tel');//,{unique:true} } console.log('newDB or db version changed to ( ' + version+')'); }; //成功打开已经创建好的数据库 request.onsuccess = function(e){ //DBdescribe.db获取数据库对象,成为全局对象 DBdescribe.db = e.target.result; console.log("onsuccess success"); //加载好就遍历indexDB TraversalDbByCursor(DBdescribe.db,tableName); //将事件绑定在 请求成功之中, //这时候dom加载完毕 //window.onload=function(){ document.getElementById("addbtn").addEventListener("click",function(){ var name=document.getElementById("name").value; var address=document.getElementById("address").value; var tel=document.getElementById("tel").value; var model={name:name,address:address,tel:tel};//键不用“” var modelArr=[{name:name,address:address,tel:tel}];//键不用“” alert(model.name); addOneData(DBdescribe.db,tableName,model); TraversalDbByCursor(DBdescribe.db,tableName); }) //} }; } /* 增删改都用 db,table-->transaction(function)-->table(function)->request->cursor||model */ //插入多条数据(数组) table.add function addDataArray(db,tableName,arr){ var transaction=db.transaction(tableName,'readwrite'); var table=transaction.objectStore(tableName); for(var i=0;i<arr.length;i++){ table.add(arr[i]); } } //插入一条数据 table.add function addOneData(db,tb,model){ // var transaction = event.target.transaction;// var transaction=db.transaction(tb,'readwrite'); var table=transaction.objectStore(tb); table.add(model); } //1,查找数据table.get // db tb->transaction->table.get()->request-> function getDataByKey(db,tb,value){ var transaction=db.transaction(tb,'readwrite'); var table=transaction.objectStore(tb); var request=table.get(value); request.onsuccess=function(e){ var student=e.target.result; console.log(student.name); }; } //2,索引查找数据table.index function getDataByIndex(db,tb){ var transaction=db.transaction(tb); var table=transaction.objectStore(tb); var index = table.index("nameIndex");/* ****重点*/ index.get('Byron').onsuccess=function(e){/* ****重点*/ var student=e.target.result; console.log(student.id); } } //3,遍历db的table,事务和游标 。db,tb -->transaction --> table-->cursor function TraversalDbByCursor(db,tb){ var transaction=db.transaction(tb); var table=transaction.objectStore(tb); var request= table.openCursor();//C大写 $("#renderArea").empty(); request.onsuccess=function(e){ //类似 while循环 var cursor=e.target.result; if (cursor) { var personkey = cursor.key;//1...n var personvalue = cursor.value;//每个json对象 console.log(personkey+personvalue); addToHtml(personvalue); cursor.continue(); } } } //更新数据 command-->request(e)-->goal function updateDataByKey(db,tableName,value){ var transaction=db.transaction(tableName,'readwrite'); var table=transaction.objectStore(tableName); var request=table.get(value); request.onsuccess=function(e){ var student=e.target.result; student.age=35; table.put(student); }; } //删除数据 table.delete function deleteDataByKey(db,tableName,value){ var transaction=db.transaction(tableName,'readwrite'); var table=transaction.objectStore(tableName); table.delete(value); } //清空table数据 table.clear function clearObjectStore(db,tableName){ var transaction=db.transaction(tableName,'readwrite'); var table=transaction.objectStore(tableName); table.clear(); } //关闭数据库db.close function closeDB(db){ db.close(); } //删除数据库 function deleteDB(name){ indexedDB.deleteDatabase(name); } function addToHtml(option){ //$("#renderArea").empty(); $("#renderArea").append('<div class="item">'+option.name+'</div>'); $("#renderArea").append('<div class="item">'+option.address+'</div>'); $("#renderArea").append('<div class="item">'+option.tel+'</div>'); $("#renderArea").append('<div class="item del">删除</div>'); } //closeDB(myDB.db);//关闭数据库 打开和关闭数据库不能同时存在??? // deleteDB(myDB.name);//删除数据库 </script> <style type="text/css"> .box{ display: flex; flex-flow: row wrap; justify-content:space-around; ; align-content: flex-start; width:600px; height:500px; background: tomato; border-radius: 5px; } .item{ display: flex; align-items:center; justify-content:center; box-sizing: border-box; border-radius: 5px; margin:0 40px; width:60px; height: 30px; border:2px solid yellowgreen; background: lightgreen; } .title{ width:150px; display:inline-block; text-align: center; } .del{cursor: pointer;} </style> </head> <body> 姓名: <input type="text" id="name" /> 电话: <input type="text" id="tel" /> 地址: <input type="text" id="address" /> <br/> <button id="addbtn" >增加</button> <button id="deletebtn">删除</button> <button id="moltifybtn">修改</button> <button id="clearbtn">清空</button> <br/> <input type="text" id="txt" /> <button id="searchbtn">查询</button> <br/> <span class="title" >姓名</span> <span class="title" >电话</span> <span class="title" >地址</span> <span class="title" >删除</span> <div id="renderArea" class="box"> <!-- <div class="item">姓名</div> <div class="item">电话</div> <div class="item">地址</div> <div class="item del">删除</div> <div class="item">姓名</div> <div class="item">姓名</div> <div class="item">姓名</div> <div class="item del">删除</div> --> </div> </body> </html>
http://www.myexception.cn/nosql/1973758.html html5之indexdb(nosql存储) indexedDB是HTML5-WebStorage的重要一环,是一种轻量级NOSQL数据库。相比web sql(sqlite)更加高效,包括索引、事务处理和健壮的查询功能。indexedDB特点: 一个网站可能有一个或多个 IndexedDB 数据库,每个数据库必须具有惟一的名称。 一个数据库可包含一个或多个对象存储。一个对象存储(由一个名称惟一标识)是一个记录集合。每个记录有一个键 和一个值。该值是一个对象,可拥有一个或多个属性。键可能基于某个键生成器,从一个键路径衍生出来,或者是显式设置。一个键生成器自动生成惟一的连续正整数。键路径定义了键值的路径。它可以是单个 JavaScript 标识符或多个由句点分隔的标识符。(有点像列数据库的特点) IndexedDB中,几乎所有的操作都是采用了command->request->result的方式。比如查询一条记录,返回一个request,在request的result中得到查询结果。又比如打开数据库,返回一个request,在request的result中得到返回的数据库引用。 indexedDB需要放到web服务器上才可以运行。 1、indexedDB常用方法: 1)获得indexedDB对象:(这一步相当于传统数据库中的创建数据库) if (!window.indexedDB) { window.indexedDB = window.mozIndexedDB || window.webkitIndexedDB; } request.onupgradeneeded = function(event) { alert(event.oldVersion); db = request.result; if (db.objectStoreNames.contains('books')) { <span style="white-space:pre"> </span>db.deleteObjectStore('books'); } var store = db.createObjectStore("books", {keyPath: "isbn"}); var titleIndex = store.createIndex("by_title", "title", {unique: true}); var authorIndex = store.createIndex("by_author", "author"); // Populate with initial data. store.put({title: "Quarry Memories", author: "Fred", isbn: 123456,other:"..ceshi...."}); store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567}); store.put({title: "Bedrock Nights", author: "Barney", isbn: 3456780000000000000}); }; var request = indexedDB.open("MyTestDatabase"); request.onsuccess = function(e) { var db = request.result; } 注:indexedDB标准建议,在初始化的时候创建表。以后每次打开浏览器,只需要check版本号,不需要第二次创建。(只有当版本变化或者第一次时采调用onupgradeneeded方法) 2)初始化objectStore:(相当于传统数据库中的表) request.onupgradeneeded = function(event) { alert(event.oldVersion); db = request.result; if (db.objectStoreNames.contains('books')) { db.deleteObjectStore('books'); } var store = db.createObjectStore("books", {keyPath: "isbn"}); var titleIndex = store.createIndex("by_title", "title", {unique: true}); var authorIndex = store.createIndex("by_author", "author"); // Populate with initial data. store.put({title: "Quarry Memories", author: "Fred", isbn: 123456,other:"..ceshi...."}); store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567}); store.put({title: "Bedrock Nights", author: "Barney", isbn: 3456780000000000000}); }; 注: 1.在indexedDB中,类似列数据库,所以没有列的概念,存储的是无层次限制的json对象。 2.可以通过index创建索引。 3)事务、游标 1.在indexedDB中,事务会自动提交或回滚。所以无需手动commit或者rollback。 事务分为三种 IDBTransaction.READ_ONLY 只读 IDBTransaction.READ_WRITE 可读可写 IDBTransaction.VERSION_CHANGE 版本升级 我们用的最多的是前两种。如果不设置事务级别,则默认为READ_ONLY。 2.游标,是遍历object store的唯一方法。如果在打开游标的时候不设置,默认采用IDBCursor.NEXT。在调用了cursor.continue之后,cursor会重新调用onsuccess句柄上的方法。 // 通过IDBDatabase得到IDBTransaction var transaction = db.transaction(["customers"]); // 通过IDBTransaction得到IDBObjectStore var objectStore = transaction.objectStore("customers"); // 打开游标,遍历customers中所有数据 objectStore.openCursor().onsuccess = function(event) { var cursor = event.target.result; if (cursor) { var key = cursor.key; var rowData = cursor.value; alert(rowData.name); cursor.continue(); } } 4)索引查询: 上例中的objectStore.openCursor是根据keyPath去查询的。如果想通过某个索引去查询,可以用objectStore.index(索引名).openCursor去查询 1)openCursor的第一个参数为查询条件,他需要传入一个IDBKeyRange对象。 IDBKeyRange的创建方式有4种,都是调用了IDBKeyRange的静态方法。分别代表了4种不同类型的条件。 // 只取得当前索引的值为Bill的数据 IDBKeyRange.only("Bill"); // 只取得当前索引的值大于Bill,并且不包括Bill的数据 IDBKeyRange.lowerBound("Bill", true); // 只取得当前索引的值小于Bill,并且包括Bill的数据 IDBKeyRange.upperBound("Bill", false); // 取得当前索引的值介于Bill和Jack之间,并且包括Bill,但不包括Jack的数据 IDBKeyRange.bound("Bill", "Jack", false, true); 2)openCursor的第二个参数为游标方向。有4种 IDBCursor.NEXT 顺序循环 IDBCursor.NEXT_NO_DUPLICATE 顺序循环不重复 IDBCursor.PREV 倒序循环 IDBCursor.PREV_NO_DUPLICATE 倒序循环不重复 var boundKeyRange = IDBKeyRange.upperBound("Jack", false); objectStore.index("name").openCursor(boundKeyRange, IDBCursor.PREV_NO_DUPLICATE).onsuccess = function(event) { var cursor = event.target.result; if (!cursor) { return; } var rowData = cursor.value; alert(rowData.name); cursor.continue(); }; 2、实例: <!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://www.jeasyuicn.com/cron/jquery.min.js"></script> <script type="text/javascript"> var db = null; if (!window.indexedDB) { window.indexedDB = window.mozIndexedDB || window.webkitIndexedDB; } var request = indexedDB.open("test",3); request.onupgradeneeded = function(event) { alert(event.oldVersion); db = request.result; if (db.objectStoreNames.contains('books')) { db.deleteObjectStore('books'); } var store = db.createObjectStore("books", {keyPath: "isbn"}); var titleIndex = store.createIndex("by_title", "title", {unique: true}); var authorIndex = store.createIndex("by_author", "author"); // Populate with initial data. store.put({title: "Quarry Memories", author: "Fred", isbn: 123456,other:"..ceshi...."}); store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567}); store.put({title: "Bedrock Nights", author: "Barney", isbn: 3456780000000000000}); }; request.onsuccess = function() { db = request.result; }; //通过事务、索引获取数据 function getDatas() { var tx = db.transaction("books", "readonly"); var store = tx.objectStore("books"); var index = store.index("by_title"); var request = index.get("Bedrock Nights"); request.onsuccess = function() { var matching = request.result; if (matching !== undefined) { // A match was found. $("#d1").html(matching.isbn+";"+matching.title+";"+matching.author); } else { // No match was found. $("#d1").html(123); } }; } //通过事务、游标、索引获取数据 function getDatas1() { var tx = db.transaction("books", "readonly"); var store = tx.objectStore("books"); var index = store.index("by_author"); var request = index.openCursor(IDBKeyRange.only("Fred")); var tmp = ""; request.onsuccess = function(event) { var cursor = request.result;//也可以写成var cursor = event.target.result; if (cursor) { tmp+=cursor.value.isbn+";"+cursor.value.title+";"+cursor.value.author; cursor.continue(); } else { $("#d1").html('错误...'); } $("#d1").html(tmp); }; } function deleteDb() { var deleteDbRequest = indexedDB.deleteDatabase('test'); deleteDbRequest.onsuccess = function (event) { alert('success...'); }; deleteDbRequest.onerror = function (e) { alert('error...'); }; } </script> </head> <body> indexdb demo...<br/> <button onclick="getDatas();">获取数据</button><br/> <button onclick="getDatas1();">获取数据1</button><br/> <button onclick="deleteDb();">删除数据库</button><br/> <div id="d1"></div> </body> </html>
IndexedDB 是一个为了能够在客户端存储可观数量的结构化数据,并且在这些数据上使用索引进行高性能检索的 API。虽然 DOM 存储 对于存储少量数据是非常有用的,但是它对大量结构化数据的存储就显得力不从心了。IndexedDB 则提供了这样的一个解决方案。 IndexedDB 分别为同步和异步访问提供了单独的 API 。同步 API 本来是要用于仅供 Web Workers 内部使用,但是还没有被任何浏览器所实现。异步 API 在 Web Workers 内部和外部都可以使用,另外浏览器可能对indexDB有50M大小的限制,一般用户保存大量用户数据并要求数据之间有搜索需要的场景。
- 异步API
异步 API 方法调用完后会立即返回,而不会阻塞调用线程。要异步访问数据库,要调用 window 对象 indexedDB 属性的 open() 方法。该方法返回一个 IDBRequest 对象 (IDBOpenDBRequest);异步操作通过在 IDBRequest 对象上触发事件来和调用程序进行通信。
- IDBFactory 提供了对数据库的访问。这是由全局对象 indexedDB 实现的接口,因而也是该 API 的入口。
- IDBCursor 遍历对象存储空间和索引。
- IDBCursorWithValue 遍历对象存储空间和索引并返回游标的当前值。
- IDBDatabase 表示到数据库的连接。只能通过这个连接来拿到一个数据库事务。
- IDBEnvironment 提供了到客户端数据库的访问。它由 window 对象实现。
- IDBIndex 提供了到索引元数据的访问。
- IDBKeyRange 定义键的范围。
- IDBObjectStore 表示一个对象存储空间。
- IDBOpenDBRequest 表示一个打开数据库的请求。
-IDBRequest 提供了到数据库异步请求结果和数据库的访问。这也是在你调用一个异步方法时所得到的。
- IDBTransaction 表示一个事务。你在数据库上创建一个事务,指定它的范围(例如你希望访问哪一个对象存储空间),并确定你希望的访问类型(只读或写入)。
- IDBVersionChangeEvent 表明数据库的版本号已经改变。
- 同步API
规范里面还定义了 API 的同步版本。同步 API 还没有在任何浏览器中得以实现。它原本是要和 webWork 一起使用的。
知识没有高低贵贱之分。