webSQL已于2010年11月18日被W3C废弃,目前仅在chrome和safari等部分webkit浏览器使用,所以不选择使用(他是关系型数据库)。
Web Storage(Local Storage和Session Storage)使用字符串键值对存储数据,根据不同浏览器存储容量在2.5M-10M之间,对于大量结构化数据会不够用,所以W3C推出了IndexedDB,容量250M。
IndexedDB也是使用键值对,类似非关系型数据库;并且它是异步执行,不同于Web Storage是同步执行;它提供了索引功能,查询速度快。
创建一个数据库:
function openDB (name,version) {
var version=version || 1;
var request=window.indexedDB.open(name,version);
request.onerror=function(e){//创建失败
console.log(e.currentTarget.error.message);
};
request.onsuccess=function(e){//创建成功
myDB.db=e.target.result;
};
request.onupgradeneeded=function(e){//升级版本号,修改数据库结构(新增或删除表、索引或者主键),只能通过升级数据库版本完成
console.log('DB version changed to '+version);
};
}
var myDB={
name:'test',
version:2,
db:null
};
关闭和删除数据库:
function closeDB(db){//关闭
db.close();
}
function deleteDB(name){//删除
indexedDB.deleteDatabase(name);
}
closeDB(myDB.db);
deleteDB(myDB.name);
创建表(objectStore):
indexedDB没有表这个概念,而是objectStore,一个数据库可以有多个objectStore,它可以存放多种数据类型,以键值对方式。
我们可以指定每条记录的一个共有字段当作主键(keyPath),也可以指定递增数字作为主键(keyGenerator),也可以不指定。选择不同的键类型,objectStore可以存储的数据结构也有差异。
键类型 | 存储数据 |
不使用 | 任意值,但是没添加一条数据的时候需要指定键参数 |
keyPath | Javascript对象,对象必须有一属性作为键值,如id |
keyGenerator | 任意值 |
都使用 | Javascript对象,如果对象中有keyPath指定的属性则不生成新的键值,如果没有自动生成递增键值,填充keyPath指定属性 |
例创建一个表:
request.onupgradeneeded = function(e) {
console.log('DB version changed to '+version);
myDB.db = e.target.result;
var objectStore;
if (!myDB.db.objectStoreNames.contains('table1')) {//升级版本号,修改数据库结构(新增或删除表、索引或者主键),只能通过升级数据库版本完成
objectStore = myDB.db.createObjectStore('table1', { keyPath: 'id' });//以数据对象的一个属性作为主键
// objectStore = myDB.db.createObjectStore('table1', { autoIncrement: true });//以递增数字作为主键
}
}
事务
数据记录的读写删改,都要通过事务完成,事务对象提供error、abort和complete三个事件,用来监听操作结果。
新建事务时必须指定用哪些表格和操作模式("只读"或"读写")
写入数据:
写入操作是一个异步操作,通过监听连接对象的success
事件和error
事件,了解是否写入成功。
var persons=[{
id:1001,
name:"A",
age:6
},{
id:1002,
name:"B",
age:7
},{
id:1003,
name:"C",
age:8
}];
function addData(db,storeName){
var transaction=db.transaction(storeName,'readwrite'); //新建事务时必须指定用哪些表格和操作模式("只读"或"读写")
var table1=transaction.objectStore(storeName);
for(var i=0;i
读取数据:
function readData(storeName,id){
var transaction=myDB.db.transaction(storeName);
var table1=transaction.objectStore(storeName);
var request = table1.get(id);
request.onsuccess = function (event) {
console.log('数据成功读取');
console.log(request)
};
}
setTimeout(function(){
readData('table1',1001);
},1000);
数据修改:
function update(storeName,value){
var transaction=myDB.db.transaction(storeName,'readwrite');
var table1=transaction.objectStore(storeName);
var request = table1.put(value);
request.onsuccess = function (event) {
console.log('数据成功修改');
console.log(request)
};
}
setTimeout(function(){
update('table1',{ id:1001, name:"AA", age:66, sex:'male' });
},1000);
删除数据:
function deleteData(storeName,id){
var transaction=myDB.db.transaction(storeName,'readwrite');
var table1=transaction.objectStore(storeName);
var request = table1.delete(id);
request.onsuccess = function (event) {
console.log('数据成功删除');
console.log(request)
};
}
setTimeout(function(){
deleteData('table1',1001);
},1000);
数据遍历(游标):
数据遍历需要用到游标
function readAllData(storeName){
var transaction=myDB.db.transaction(storeName,'readwrite');
var table1=transaction.objectStore(storeName);
var request = table1.openCursor();
request.onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log(cursor);
cursor.continue();
} else {
console.log('没有更多数据了!');
}
};
}
setTimeout(function(){
readAllData('table1');
},1000);
索引:
数据库的索引可以快速的定位数据,可以让你指定任意字段作为键来搜索数据,如果不建立索引,那默认只能搜索主键。主键是索引的一种(唯一性非空索引的一种)。
创建索引:
request.onupgradeneeded = function(e) {
myDB.db = e.target.result;
var objectStore;
if (!myDB.db.objectStoreNames.contains('table1')) {//升级版本号,修改数据库结构(新增或删除表、索引或者主键),只能通过升级数据库版本完成
objectStore = myDB.db.createObjectStore('table1', { keyPath: 'id' });//以数据对象的一个属性作为主键
// objectStore = myDB.db.createObjectStore('table1', { autoIncrement: true });//以递增数字作为主键
/*****创建索引*****/
objectStore.createIndex('nameIndex','name',{unique:true}); //createIndex方法有三个参数,索引名、索引字段名、索引字段值是否唯一
objectStore.createIndex('ageIndex','age',{unique:false});
}
}
有了索引,我们可以方便快捷的获取数据:
function readByIndex(storeName,indexname,name){
var transaction=myDB.db.transaction(storeName);
var table1=transaction.objectStore(storeName);
var index1=table1.index(indexname);
index1.get(name).onsuccess = function (event) {
var request = event.target.result;
console.log('索引读取成功');
console.log(request);
};
}
setTimeout(function(){
readByIndex('table1','ageIndex',6);
},1000);
但是这样只能读取重复数据的第一条,剩下的读取不到