6

在大多数教程中,它展示了如何通过使用游标迭代它们来从对象存储中检索所有记录。但是如何通过键“myKey”从对象存储中检索值?

4

2 回答 2

9

如果您正在寻找简单的键/值存储,那么您可能需要考虑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 );

然后,您可以添加一个onsuccessonerror回调来解析结果事件对象,您将要从中提取event.target.result值。

2)如果myKey在非主索引中(创建存储后添加的索引),则在事务上打开索引,然后在索引上打开游标。

var transaction_index = transaction.index( index );
var request = transaction_index.get( key );

至于游标(您可能会更频繁地讨论游标,因为每当您在同一个键下存储多个值时都需要一个),您也可以使用它们来检索单个键的值。规格说:

键范围可以由单个值组成。

您需要keyRange使用该IDBKeyRange对象生成一个。这是来自MIT 许可的 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 );
于 2011-11-29T02:30:55.710 回答
2

有一些库可以帮助您使用 IndexedDB,例如DexieJsStoreLocalForageSFDatabase-js

对我来说,使用SFDatabase-js更容易,因为在使用 MySQL/Redis 作为数据库时,用法与PHP 版本几乎相似。它也适用于 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"}]
于 2019-06-30T03:07:55.157 回答