// In the following line, you should include the prefixes of implementations you want to test.window.indexedDB =window.indexedDB ||window.mozIndexedDB ||window.webkitIndexedDB ||window.msIndexedDB;// DON'T use "var indexedDB = ..." if you're not in a function.// Moreover, you may need references to some window.IDB* objects:window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers
window.IDBKeyRange =window.IDBKeyRange ||window.webkitIDBKeyRange ||window.msIDBKeyRange;// (Mozilla has never prefixed these objects, so we don't need window.mozIDB*)
// This event is only implemented in recent browsers request.onupgradeneeded=function(event) { // Save the IDBDatabase interface var db =event.target.result;// Create an objectStore for this databasevar objectStore =db.createObjectStore("name", { keyPath:"myKey" });};
注意,这里的版本号是一个整数。如果你传入一个float,那么将会对该float进行取整操作。
有了request,我们可以通过监听onerror或者onsuccess事件来进行相应的处理。
var db;var request =indexedDB.open("MyTestDatabase");request.onerror=function(event) {console.log("Why didn't you allow my web app to use IndexedDB?!");};request.onsuccess=function(event) { db =event.target.result;};
拿到db对象之后,我们可以设置全局的异常处理:
db.onerror=function(event) {// Generic error handler for all errors targeted at this database's// requests!console.error("Database error: "+event.target.errorCode);};
// This is what our customer data looks like.constcustomerData= [ { ssn:"444-44-4444", name:"Bill", age:35, email:"bill@company.com" }, { ssn:"555-55-5555", name:"Donna", age:32, email:"donna@home.org" }];
看一下对应的数据库操作是怎么样的:
constdbName="the_name";var request =indexedDB.open(dbName,2);request.onerror=function(event) {// Handle errors.};request.onupgradeneeded=function(event) {var db =event.target.result;// Create an objectStore to hold information about our customers. We're// going to use "ssn" as our key path because it's guaranteed to be// unique - or at least that's what I was told during the kickoff meeting.var objectStore =db.createObjectStore("customers", { keyPath:"ssn" });// Create an index to search customers by name. We may have duplicates// so we can't use a unique index.objectStore.createIndex("name","name", { unique:false });// Create an index to search customers by email. We want to ensure that// no two customers have the same email, so use a unique index.objectStore.createIndex("email","email", { unique:true });// Use transaction oncomplete to make sure the objectStore creation is // finished before adding data into it.objectStore.transaction.oncomplete=function(event) {// Store values in the newly created objectStore.var customerObjectStore =db.transaction("customers","readwrite").objectStore("customers");customerData.forEach(function(customer) {customerObjectStore.add(customer); }); };};
// Do something when all the data is added to the database.transaction.oncomplete=function(event) {console.log("All done!");};transaction.onerror=function(event) {// Don't forget to handle errors!};var objectStore =transaction.objectStore("customers");customerData.forEach(function(customer) {var request =objectStore.add(customer);request.onsuccess=function(event) {// event.target.result === customer.ssn; };});
var request =db.transaction(["customers"],"readwrite").objectStore("customers").delete("444-44-4444");request.onsuccess=function(event) {// It's gone!};
现在我们的数据库已经有了数据,我们看下怎么进行查询:
var transaction =db.transaction(["customers"]);var objectStore =transaction.objectStore("customers");var request =objectStore.get("444-44-4444");request.onerror=function(event) {// Handle errors!};request.onsuccess=function(event) {// Do something with the request.result!console.log("Name for SSN 444-44-4444 is "+request.result.name);
这里,我们直接使用了db.transaction,默认情况下是readonly模式的。
下面是一个更新的例子:
var objectStore =db.transaction(["customers"],"readwrite").objectStore("customers");var request =objectStore.get("444-44-4444");request.onerror=function(event) {// Handle errors!};request.onsuccess=function(event) {// Get the old value that we want to updatevar data =event.target.result;// update the value(s) in the object that you want to changedata.age =42;// Put this updated object back into the database.var requestUpdate =objectStore.put(data);requestUpdate.onerror=function(event) {// Do something with the error };requestUpdate.onsuccess=function(event) {// Success - the data is updated! };};
更新我们使用的是put方法。
使用游标cursor
indexedDB支持游标操作,我们可以使用cursor来遍历objectStore的数据:
var objectStore =db.transaction("customers").objectStore("customers");objectStore.openCursor().onsuccess=function(event) {var cursor =event.target.result;if (cursor) {console.log("Name for SSN "+cursor.key +" is "+cursor.value.name);cursor.continue(); }else {console.log("No more entries!"); }};
// Only match "Donna"var singleKeyRange =IDBKeyRange.only("Donna");// Match anything past "Bill", including "Bill"var lowerBoundKeyRange =IDBKeyRange.lowerBound("Bill");// Match anything past "Bill", but don't include "Bill"var lowerBoundOpenKeyRange =IDBKeyRange.lowerBound("Bill",true);// Match anything up to, but not including, "Donna"var upperBoundOpenKeyRange =IDBKeyRange.upperBound("Donna",true);// Match anything between "Bill" and "Donna", but not including "Donna"var boundKeyRange =IDBKeyRange.bound("Bill","Donna",false,true);// To use one of the key ranges, pass it in as the first argument of openCursor()/openKeyCursor()index.openCursor(boundKeyRange,"prev").onsuccess=function(event) {var cursor =event.target.result;if (cursor) {// Do something with the matches.cursor.continue(); }};
除了openCursor,我们还可以通过使用openKeyCursor来遍历KeyCursor:
// Using a normal cursor to grab whole customer record objectsindex.openCursor().onsuccess=function(event) {var cursor =event.target.result;if (cursor) {// cursor.key is a name, like "Bill", and cursor.value is the whole object.console.log("Name: "+cursor.key +", SSN: "+cursor.value.ssn +", email: "+cursor.value.email);cursor.continue(); }};// Using a key cursor to grab customer record object keysindex.openKeyCursor().onsuccess=function(event) {var cursor =event.target.result;if (cursor) {// cursor.key is a name, like "Bill", and cursor.value is the SSN.// No way to directly get the rest of the stored object.console.log("Name: "+cursor.key +", SSN: "+cursor.primaryKey);cursor.continue(); }};
除此之外,我们还可以直接通过index来进行查询:
var index =objectStore.index("name");index.get("Donna").onsuccess=function(event) {console.log("Donna's SSN is "+event.target.result.ssn);};