【发布时间】:2012-01-05 13:37:05
【问题描述】:
在大多数教程中,它展示了如何通过使用游标迭代它们来从对象存储中检索所有记录。 但是如何通过键“myKey”从对象存储中检索值?
【问题讨论】:
在大多数教程中,它展示了如何通过使用游标迭代它们来从对象存储中检索所有记录。 但是如何通过键“myKey”从对象存储中检索值?
【问题讨论】:
如果您正在寻找简单的键/值存储,那么您可能需要考虑localStorage。它比使用 IndexedDB 简单得多。它仅适用于字符串(到目前为止),但对象很容易通过 JSON 对象进行字符串化。
console.log( 'BEFORE', localStorage.getItem( 'test-key' ) );
localStorage.setItem( 'test-key', JSON.stringify( { 'foo': Math.round( Math.random() * 1000 ) } ) );
console.log( 'AFTER', JSON.parse( localStorage.getItem( 'test-key' ) ) );
也就是说,您不需要游标来从 IndexedDB 中的键获取单个值,仅当您需要为键或键范围获取多个值时。要从键中获取值,您可以执行以下两项操作之一:
1) 如果myKey 是您的主键(创建商店时添加):
var request = transaction.get( key );
然后您可以添加一个onsuccess 和onerror 回调来解析生成的事件对象,您需要从中提取event.target.result 值。
2) 如果myKey 位于非主索引中(您在创建存储后添加的索引),则在事务上打开索引,然后在索引上打开光标。
var transaction_index = transaction.index( index );
var request = transaction_index.get( key );
至于游标(您可能会更频繁地讨论游标,因为每当您在同一个键下存储多个值时都需要一个),您也可以使用它们来检索单个键的值。说the spec:
键范围可以由单个值组成。
您需要使用IDBKeyRange 对象生成keyRange。这是来自MIT-licensed InDB(我正在开发的IndexedDB 包装器)的辅助方法,它处理在单个值(例如InDB.range.get( value ))或键范围上打开游标。
InDB.range.get = function ( value, left_bound, right_bound, includes_left_bound, includes_right_bound ) {
if ( InDB.exists( left_bound ) && InDB.exists( right_bound ) && InDB.exists( includes_left_bound ) && InDB.exists( includes_right_bound ) ) {
return IDBKeyRange.bound( left_bound, right_bound, includes_left_bound, includes_right_bound );
} else if ( InDB.exists( left_bound ) && InDB.exists( includes_left_bound ) ) {
return IDBKeyRange.lowerBound( left_bound, includes_left_bound );
} else if ( InDB.exists( right_bound ) && InDB.exists( includes_right_bound ) ) {
return IDBKeyRange.upperBound( right_bound, includes_right_bound );
} else if ( InDB.exists( value ) ) {
return IDBKeyRange.only( value );
} else {
return false;
}
}
拥有keyRange 后,您可以做以下两件事之一:
1) 如果myKey 是您的主键(在创建商店时添加),您会在交易上打开一个常规光标(带有可选方向)。
var request = transaction.openCursor( keyRange, direction );
2) 如果myKey 位于非主索引中(您在创建存储后添加的索引),则在事务上打开索引,然后在索引上打开光标。
var transaction_index = transaction.index( index );
var request = transaction_index.openCursor( keyRange, direction );
【讨论】:
objectStore 上调用get() 是正确的。 transaction 的 var 声明未在此处显示,但类似于 event.objectStore( database )。
var event = database.transaction( [ database ], type, timeout );
有一些库可以帮助您使用 IndexedDB,例如 Dexie、JsStore、LocalForage 和 SFDatabase-js。
对我来说,使用SFDatabase-js 更容易,因为在使用 MySQL/Redis 作为数据库时,其用法与 PHP version 几乎相似。它也适用于 NodeJS。
您只需要定义数据库索引结构并初始化数据库即可。
var myDB = new SFDatabase('myDB', {
websql:false,
idbVersion:1,
databaseStructure:{
Users:{
// rowid -> always unique and incremental
name:['text', 'unique']
}
}
}, function(){
// database initialized
});
之后,您几乎可以在数据库中存储任何内容。
myDB.insert('Users', {name:"Alex", age:17});
myDB.insert('Users', {name:"Ander", age:12});
myDB.insert('Users', {name:"Bell", age:30, admin:true});
如果您想获取单行数据,可以使用get。
myDB.get('Users', 'age', {name:"Ander"}, console.log);
//-> 12
myDB.get('Users', ['name', 'age'], {admin:true}, console.log);
//-> {name:"Bell", age:30}
并且还获取多行数据。
// Age more than 15
myDB.select('Users', ['name'], {'age[>]':15}, console.log);
//-> [{name: "Alex"}, {name: "Bell"}]
// Any name with 'e' and without 'A', and limit to two result
myDB.select('Users', ['name'], {'name[~]':'e', 'name[!~]'=>'A', LIMIT:2}, console.log);
//-> [{name: "Bell"}]
【讨论】: