indexedDB 操作库IDBWRAPPER 教程翻译及API翻译第一部分part1
indexedDB是html5出来后弄出来的客户端数据持久化方式的一种。可以以JSON对象方式存储数据至本地。相关的基本概念请自行查找相关资料。
为什么需要一个库来操作IndexedDB呢?
第一:浏览器兼容性问题,现在indexedDB只支持chrome与firefox
第二:操作IndexedDB的方法接口比较复杂。为什么复杂,请看相关的一些个老外的讨论
https://groups.google.com/a/chromium.org/forum/?fromgroups=#!topic/chromium-html5/3wCwyJtBS_0
============================== 分割线 ===================================
所以一个老外,写了一个JS库IDBWRAPPER来解决上面两个问题。我也是无意中搜到的。
IDBWRAPPER项目github地址
https://github.com/jensarps/IDBWrapper
============================== 分割线 ===================================
教程分为两部分
开始第一部分的基础教程
Step one: open the store 来吧骚年开始第一步:
先弄个HTML页引用IDBStore.js引用这个库
<!DOCTYPE html> <html> <head> <title>IDBWrapper Tutorial, Step 1</title> </head> <body> <script type="text/javascript" src="IDBStore.js"></script> <script type="text/javascript" src="tutorial.js"></script> </body> </html>
使用IDBWRAPPER创建一个名为customer的indexedDB
var customers = new IDBStore({ dbVersion: 1, storeName: 'customer', keyPath: 'id', autoIncrement: true, onStoreReady: function(){ console.log('Store ready!'); } });
构造时的参数:
· storeName: 选一个有意义的名字即可
· dbVersion: 传一个int类型的值,从1开始,并且只有当构造器有变化时才往上增
· keyPath: 唯一主键索引,比如id字段
· autoIncrement: 主键自增,如果你不想管理主键的话就设为true
onStoreReady: 创建完毕后的回调,所有数据库操作都得在这个函数内
IDBwrapper will open the database, check if a store with the given name exists and if not, it will create it using the above properties. You’ll then get an IDBStore instance back that you can use to work with the store. Once the store is created, it’s persistent. But, if you need to delete and re-create it (for example, if you happened to pick the wrong value for keyPath), you can delete the store using thedeleteObjectStore
method.
IDBwrapper会打开一个数据库,在store中检测传入的storeName是否存在,如果不存在则会使用传入的参数新建一个数据库。 然后你丫就会得到一个IDBStore的实例,并可对其进行相应的操作了, 一旦store创建了,则会持久性的,但如果你需要删除并重建它(举个栗子: 你设错了keyPath想修改一下)的话,你可以使用通过 deleteObjectStore方法删除它
Inside IndexedDB: IDBWrapper works with one store; when you do a new IDBStore()
it represents one store in an IndexedDB. If you want multiple stores inside of the same IndexedDB, you’d have to do a new IDBStore()
for each store. This is an artificial limitation of IDBWrapper; if you work with IndexedDB directly, you can lock multiple stores when starting a transaction. This be useful when you want to update one store depending on the information found in another store, and you want to prevent this other store’s contents to change during your update action.
在内部,IDBWrapper只在一个store内操作, 当你执行一个new IDBStore()操作时,代表着在IndexedDB内创建了一个store。如果你想在在一个IndexedDB内拥有多个store,你必须再new IDBStore一个。这是IDBWrapper人为限制的。如果当执行一个事务时,直接操作IndexedDB,你能锁掉多个store。这对于你想更新一个store且依赖于另一个store中的信息并且更新时不想另一个store中的信息被更改掉时非常有用
关于IndexedDB“ 锁表”的概念我在stackoverflow上搜索到某个人的回答如下:
The IndexedDB specifications determine that "If multiple READ_WRITE transactions are attempting to access the same object store (i.e. if they have overlapping scope), the transaction that was created first must be the transaction which gets access to the object store first. Due to the requirements in the previous paragraph, this also means that it is the only transaction which has access to the object store until the transaction is finished."
That means that when a transaction is in a READ_WRITE mode the objectStore will be locked for other READ_WRITE transactions up until the transaction will finish.
意思就是当多个拥有read_write权限的事务操作同一个store中的同笔数据时,同一时间内只有先创建的事务才有权限操作。直到这个事务操作完毕,其它事务才能继续操作。
再详细的关于“锁表”的概念请看W3C上的解释:http://www.w3.org/TR/IndexedDB/#dfn-mode
Step 2: storing a customer 第二步存一入个”customer”对象
var dude = { firstname: 'John', lastname: 'Doe', age: 52, emails: [ '[email protected]', '[email protected]' ] }; var onsuccess = function(id){ console.log('Yeah, dude inserted! insertId is: ' + id); } var onerror = function(error){ console.log('Oh noes, sth went wrong!', error); } customers.put(dude, onsuccess, onerror);
customers即你之前生丰的indexedDB的实例
Note how we don’t have an id
property on the dude object, as we specified autoIncrement as true, so the database will take care of this. In the onsuccess
callback we’ll get the id of the newly inserted record back. Also, see how we attached an array of emails to the record? In a relational database you’d set up a different table for email addresses – no need to do that in IndexedDB.
Inside IndexedDB: Make sure to wait until the store is ready before operating on it! The whole nature of IndexedDB is asynchronous. Whatever you do, you will have to work with callbacks. There is, however, also a draft for a specification of a synchronous API, but that is not implemented in any browser (and I don’t think this is going to happen anytime soon).
注意:我们没有在dude这个对象中设置 id属性,因为数据库之前被设置了autoIncrement=true即数据库自动管理。在成功回调中我们会拿到新插入的记录的id。还有emails这个属性的值是一个数组,如果是在传统的关系型数据库中,你得再建一张不同的表来存这些数据,但在IndexedDB中不再需要了, 亲。
Step 3: reading the customer back from the store 从数据库中读取刚存入的数据
var id = 1; // Or whatever you got returned. var onsuccess = function(data){ console.log('here is our dude:', data); } var onerror = function(error){ console.log('Oh noes, sth went wrong!', error); } customers.get(id, onsuccess, onerror);
We just pass the id we got after inserting to the get method, and there we have our record from the store. It’s exactly the same thing we stored earlier, with one exception: the object now has the id
property which has been attached to it by the database.
Inside IndexedDB: What we pass as first parameter to the get
method is thekeyPath value. That means when we pass 1 to it, the database will look for an object that has 1 as value in it’s keyPath property, which we set to ‘id’ when we created the store.
在get方法中我们传入了之前在put数据成功后的回调函数内取得的id, 就取得了我们之前的记录。这和存进去的数据的像极了, 除了多了一个自动生成的id之外
在IndexedDB内部: 我们传给get方法的第一个参数就被当作keyPath的值, 即当我们传1进去,数据库就会检索到某个涵有keyPath (id)属性值为1对象。这个对象就是我们之前创建时设置过此id的对象
Step 4: updating data 更新数据
var updatedDude = { id: 1, // or whatever id our dude has firstname: 'John', lastname: 'Doe', age: 53, // dude is now a year older emails: [ '[email protected]', '[email protected]' ] }; var onsuccess = function(id){ console.log('Yeah, dude updated! id still is: ' + id); } var onerror = function(error){ console.log('Oh noes, sth went wrong!', error); } customers.put(updatedDude, onsuccess, onerror);
To update a record, you also use the put method: If there already is an object in the store with the same keyPath value (the id), it will simply overwrite it. Note that it will really, really overwrite the existing object, which means you cannot simply put a modified property of it, but have to put the whole object, including all properties.
Inside IndexedDB: keyPath values are also Type-sensitive. That means, if the id of our dude is 1 and of type Number, you have to pass numeric 1 to the get method to retrieve the dude, and for updates the value of the id property needs to be numeric 1. If you use “1″ as String, IndexedDB will think of it as a different value.
更新数据时你依然要用到put这个方法。如果已存在一个相同id的对象,则会自动覆盖上去。注意:这个覆盖的意思是指完全替换掉原来的对象,你在更新时不能只指定某一个属性,你得把所有属性写全喽
在IndexedDB内部:keyPath的值是数据类型敏感的, 这意味着,dude对象的id是1且类型是Number, 你就必须也传一个Number类型的1进去得到dude对象, 更新操作也一样需要正确的传递对应的数据类型, 如果你传了一个字符类型“1”的进去,IndexedDB会认为这是另一个keyPath值
Step 5: getting all items 读取数据库中所有数据
var onsuccess = function(data){ console.log('Here is what we have in store ('+data.length+' items in total):'); data.forEach(function(item){ console.log(item); }); } var onerror = function(error){ console.log('Oh noes, sth went wrong!', error); } customers.getAll(onsuccess, onerror);
Nothing really to say about it. Just one note: IDBStore has default error handlers for every async method that prints potential errors to the console. So if you’re just playing around you don’t need to pass your own handler to the methods.
此处没啥可讲的,唯一要注意的就是IDBStore 的所有异步方法都有默认的错误处理函数,错误处理函数会在控制台打印出潜在的错误信息。所以你只是玩玩的话,也可以不用传onerror这个错误回调
Step 6: deleting an item 删除数据记录
var id = 1; var onsuccess = function(result){ if(result !== false){ console.log('deletion successful!'); } } var onerror = function(error){ console.log('Oh noes, sth went wrong!', error); } customers.remove(id, onsuccess, onerror);
Different browsers and versions return different values to the success callback; that’s why there is an extra check in the success callback.
删除数据记录也没啥好讲的。不同浏览器(或相同浏览器的不同版本)在成功回调中返回的数据会不一样。这就是为啥在成功回调中有额外的检测了
Step 7: clearing the store 清除数据表
var onsuccess = function(){ console.log('now the store is clean again!'); } var onerror = function(error){ console.log('Oh noes, sth went wrong!', error); } customers.clear(onsuccess, onerror);
If you need to clear the store from all stored entries, you can use the clear method. Note that this won’t reset Chrome’s autoIncrement counter.
如果你需要清除store(数据表)就调用clear这个方法吧。注意:清空表,在chrome下autoIncrement计数器不会被重置,应该说自增长的id不会被重置为0
Now you know everything to do basic IndexedDB data operations with IDBWrapper. Make sure to check out the examples and the documentation!
就是这些了。感谢专心看完第一部教程的同学们。
现在我们了解了用IDBWrapper.对IndexedDB 数据的基本操作。用上面的例子试试吧。
例子,文档什么的上他的网站下吧。
第二部分的教程,随后再发吧。。。。
=========================== my name is 分割 ===============================
作者的博客,也是教程地址,英文版的http://jensarps.de/2011/11/25/working-with-idbwrapper-part-1/
=========================== my name is 分割===============================
本人英文水平绝对有限,入门后还请看英文版的官方博客哟。
注:转载请注明出处:偷饭猫email: [email protected]