您的位置:首页 > 数据库

PhoneGap -数据库操作-存储

2015-05-31 00:11 363 查看
学习要点:

1. localStorage 2. Web Sql

其中localStorage非常简单,就是一个简单的存储,看看API即可掌握;重点学会使用Web Sql



简单看看API:

一、 localStorage 和 sessionStorage

为了替代Cookile这门古老的客户端存储技术,Html5的WEB Storage Api 提供了俩中在客户端存储数据库的方法:localStorage 和sessionStorage



sessionStorage 用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此 sessionStorage 不是一种持久化的本地存储,仅仅是会话级别的存储。

而localStorage 用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。



localStorage和 sessionStorage通过window 对象访问



window.localStorage.setItem(“theme” ,”blue charm”);



setItem 存储value



用途:将value 存储到 key 字段 用法:.setItem( key, value)

代码示例: sessionStorage.setItem("key", "value"); localStorage.setItem("site", "js8.in");

getItem获取value



用途:获取指定 key本地存储的值 用法:.getItem(key)

代码示例: var value = sessionStorage.getItem("key"); var site = localStorage.getItem("site");



removeItem删除key

用途:删除指定 key本地存储的值

用法:.removeItem(key)

代码示例: sessionStorage.removeItem("key"); localStorage.removeItem("site");

clear清除所有的key

alue



用途:清除所有的key

alue 用法:.clear()

代码示例: sessionStorage.clear(); localStorage.clear();



其他操作方法:点操作和[]



web Storage 不但可以用自身的 setItem,getItem 等方便存取,也可以像普通对象一样用点(.) 操作符,及[]的方式进行数据存储,像如下的代码:

var storage = window.localStorage; storage.key1 = "hello"; storage["key2"] = "world";

console.log(storage.key1); console.log(storage["key2"]);



localStorage和 sessionStorage的key 和length属性实现遍历



sessionStorage 和localStorage提供的 key()和length可以方便的实现存储的数据遍历,例如下面的代码:

var storage = window.localStorage; for (var i=0, len = storage.length; i < len; i++){ var key

= storage.key(i); var value = storage.getItem(key); console.log(key + "=" + value); }



LocalStorage 最大的特点是:

1. APi 简单易用

2. 同步性 导致大数据场景下 用户需要等待

3. 存储格式单一

4. 数据操作能力有限

例子代码:在浏览器中调试 ,通过控制台即可非常直观的了解这个知识点
<!DOCTYPE html> 
<html>
<head>
<meta charset="utf-8">
<title>jQuery  Mobile  Web 应用程序</title>
<link href="../jquery.mobile-1.3.2.css" rel="stylesheet" type="text/css"/>
<script src="../jquery.js" type="text/javascript"></script>

<script src="../jquery.mobile-1.3.2.js" type="text/javascript"></script>

<script type="text/javascript">
	$(document).ready(function(){
			//document.addEventListener("deviceready", myDeviceReadyListener, false);
			myDeviceReadyListener()	
	});	
	function myDeviceReadyListener(){
	
		var ls = window.localStorage;
		
		var name='';
		
		if(ls.getItem("name")){
			console.log('1');
			name=ls.getItem("name");
		}else{
			console.log('2');
			//第一步 获取数据 
			var services_name='李四';
			name=services_name;
			ls.setItem('name',name);
		}
		ls.setItem("name","phonegap100");
		ls.setItem("password","phonegap100");
		ls.setItem("username","phonegap100");
		//alert(name);
		//ls.removeItem("name");//清楚一条数据
		
		
		//ls.clear();
		
		/*
		 * 	
			//写入localstorage
			ls.setItem('age','50');
			ls.setItem('name','zhangsan');
			ls.setItem('sex','男');
			console.log(ls.getItem("name"));
			console.log(ls.getItem("age"));
		*/
		
		//获取localstorage		

	
		
		
	/*
		ls.setItem("name","phonegap100");
		ls.setItem("password","phonegap100");
		ls.setItem("username","phonegap100");
		console.log(ls.getItem("name"));
		console.log(ls.key(0));
		
		//ls.removeItem("name");
		console.log(ls.getItem("name"));
		console.log(ls.getItem("password"));
		console.log(ls.getItem("username"));		
	
		ls.clear();
		console.log(ls.getItem("name"));
		console.log(ls.getItem("password"));
		console.log(ls.getItem("username"));
	*/
	}
</script>
</head> 
<body>
<div data-role="page" id="indexPage">
	<div data-role="header">
		<h1>phonegap100.com</h1>
	</div>
	<div data-role="content">		
				
	</div>
	<div data-role="footer">
		<h4>phonegap中文网</h4>
	</div>
</div>

</body>
</html>
调试图如下:



二、 Web Sql



此 API基于W3C WEB SQL Database Specification 和W3C Web Storage API Specification。有些设备已经提供了对该规范的实现,对于这些设备采用内置实现而非使用 PhoneGap 的实现。对于没有存储支持的设 备,PhoneGap的实现应该是完全兼容 W3C规范。

window.openDatabase(name, version, display_name, size) 该方法将创建一个新的SQL Lite数据库,并返回该Database对象。可使用该Database 对象操作数据。

1,openDatabase

phonegap官方文档中已经很清楚的标明,如果使用一个数据库首先要用window对象进行创建:

var dbShell = window.openDatabase(name, version, display_name, size);

参数:

name:标明数据库的名称

version:版本号

display_name:显示名称,与name的区别在于数据库表中,分别有这两个字段。

size:数据库的大小



详解:

之前,在利用工厂模式,创建了一个数据库对象:

function db(name,ver,dis,size){
.......
var _db = window.openDatabase(name,ver,dis,size);
_db.transaction();
}


调用function方法进行创建db对象时,new db(),里面传入的参数可以是需要的四个参数,但是,我用下面这个方法的时候就遇到了一个问题,先看方法:

<span style="font-size:18px;">var newdb = {
_db:'',
db:function(){
if(!newdb._db){
newdb._db  = window.openDatabase("database","1.0","mydatabase",10000);
return new db(newdb._db);
}
}
}</span>


疑惑:在进行调用工厂类创建数据库的时候,传入的参数竟然可以不是给定的四个参数,而是直接的传入了一个数据库对象;并且当获取到从工厂类中生成的数据库对象,其中也存在一个_db,两个数据库,究竟在执行transaction事务的时候调用的是哪一个?



上面说了这么多,都是为了铺陈,其中的过程是这样的:

//首先程序会为当前应用在data文件夹下创建一个以当前应用包名的文件夹

//当运行window.openDatabase方法后,会在该文件夹下创建一个app_database文件夹;里面创建一个Database.db数据库文件,会在这个数据库文件中创建两个表Database和Origins;Database存放在创建数据库时,填写的参数信息,Origins中存放数据库文件夹路径(path字段),默认第一次创建是在file__0/ 0000000000000001.db.这个才是我们真正创建的数据库文件。你调用数据库对象进行数据库操作都是在这个数据库下进行的。我们指定的数据库不存在时会帮我们新建一个数据库,当存在了只会返回一个已有的数据库对象。

2,SQLTransaction对象

该对象是用来操作executesql方法;执行transaction方法,在接受一个SQLTransaction对象的同时,它还会执行其中的回调函数:

db.transaction(populateDB, errorCB, successCB);


当你调用Database对象的transaction方法后,其回调函数将被调用并接收一个SQLTransaction对象。用户可以通过SQLTransaction对象多次调用executeSql来建立一个数据库事务处理。



function populateDB(tx) {
	tx.executeSql('DROP TABLE DEMO IF EXISTS');
	tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)');
	tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")');
	tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")');
}

function errorCB(err) {
   	alert("Error processing SQL: "+err);
}

function successCB() {
   	alert("success!");
}

var db = window.openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
db.transaction(populateDB, errorCB, successCB);


3,SQLResultSet对象

执行executesql方法,返回对象:SQLResultSet,对象中的属性

insertId:SQLResultSet对象通过SQL语句插入到数据库的行记录的行ID。[译注:如果插入多行的时候,返回最后一个行的ID]

rowAffected:被SQL语句改变的记录行数,如果语句没有影响任何行则设置为0。

rows:是一个SQLResultSetRowList对象,表示返回的多条记录。如果没有返回任何记录,则此对象为空。



SQLResultSet对象可以在执行executesql的成功回调函数中获取到:

参考文档中的例子:
<span style="font-size:18px;">tx.executeSql('SELECT * FROM DEMO', [], querySuccess, errorCB);</span>
第一个参数为要执行的数据库语句。与普通操纵数据库语句没太大区别。

第二个参数为一个数组对象,存放sql语句中需要的参数的数组,就是sql语句里面出现的?所需要的参数。

第三个参数为执行成功后,调用的方法,在这个函数中可以获取到结果集results.是一个sqlresultset对象

第四个参数为执行错误时候调用的方法。

接下来我们看一下querySuccess这个回调方法。

function querySuccess(tx, results) {
       // 因为没有插入记录,所以返回值为空
       console.log("Insert ID = " + results.insertId);
       // 因为这是一条查询语句所以返回值为0
       console.log("Rows Affected = " + results.rowAffected);
       // 返回查询到的记录行数量
       console.log("Insert ID = " + results.rows.length);
}




4,SQLResultSetList对象



包含SQL查询所返回的所有行数据。

属性:length: SQL查询所返回的记录行数。
方法:item:根据指定索引返回一个行记录的JavaScript对象。

总结:

db.transaction(SQLTransaction,err,sucss);
 
SQLResultSet = SQLTransaction.executesql("select * from",[],succ,err);
 
SQLResultSetList = SQLResultSet.rows;
 
item = SQLResultSetList.item(i);


phonegap 中与存储相关的对象有

Database 数据库对象

SQLTransaction 事物对象

SQLResultSet Sql结果对象

SQLResultSetList 查询返回数据集对象

SQLError Sql错误对象

localStorage 本地存储对象




Database 数据库对象:

通过openDatabase方法获得该对象

例如:

window.openDatabase(database_name, database_version, database_displayname, database_size);

var dbOne = window.openDatabase("test1", "1.0", "Test DB", 1000000);

database_name:数据库名字,
database_version:数据库版本
database_displayname:显示名字
database_size:数据库大小


创建完成后便会在/data/data/包名/app_database/dbOne.db找到刚才创建的数据库文件,可以利用DDMS查看



SQLTransaction 事物对象

phonegap没有提供直接获取事物对象的方法,而是利用Database 对象transaction方法,将事物对象传递给一个回调

函数,例如

dbOne.transaction(createATable, errorCreateTable, successCreateTable);


createATable即是一个回调函数,会将事物对象以参数的形式传进去,createATable函数

createATable(trans){ 
}


这里的trans即是传递进的事物对象,有了事物对象就可利用事物对象的executeSql方法执行sql语句

例如

createATable(trans){
trans.executeSql('CREATE TABLE IF NOT EXISTS MyTab (id unique, data)');
tx.executeSql('INSERT INTO MyTab (id, data) VALUES (1, "First row")');
tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")');
}


这样就利用数据库的事物对象创建了MyTab表并且插入了两条数据

SQLError 错误对象

SQLError对象也是以参数的形式传递给一个回调函数

在上面的方法

dbOne.transaction(createATable, errorCreateTable, successCreateTable);

errorCreateTable就是一个回调函数,如果dbOne.transaction函数执行失败,就会调用回调函数errorCreateTable

同时将SQLError对象传递进去

例如

function errorCreateTable(err)
{
alert("err code:"+err.code+"err message:"+err.message');
}
 
code和message为SQLError对象的两个属性

SQLResultSet对象
该对象是由事物对象的executeSql方法传递给回调函数,在回调函数中在对结构集对象操作,例如

tx.executeSql('SELECT * FROM MyTab', [], querySuccess, errorCB);


querySuccess即是成功执行后的回调函数,

function querySuccess(trans, results) {
alert("Returned rows = " + results.rows.length);
 
if (!resultSet.rowsAffected) {
alert('No rows affected!');
return false;
}
该函数接受两个参数:事物对象和结果集对象SQLResultSet,SQLResultSet包含三个属性

insertId 函数插入数据行的row ID

rowsAffected 改变的数据行的数量

rows:rows是一个SQLResultSetList 对象,该对象代表执行查询sql时返回的所有数据行

SQLResultSetList 查询返回的结果集对象

该对象包含一个属性 length(返回的数据行数量),一个方法item(该方法返回某个特定的数据行0
例:

function querySuccess(trans, results) {
var len = results.rows.length; 
console.log("MyTab table: " + len + " rows found.");
for (var i=0; i<len; i++){
console.log("Row = " + i + " ID = " + results.rows.item(i).id + " Data = " + results.rows.item(i).data);
}
}


完整的例子:在浏览器或者手机是都可以调试,效果非常好,容易理解:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>html5-dataBase</title>
</head>

<body>
<script type="text/javascript">

//1.如果数据库存在 则打开  不存在的则创建 然后在打开
var db = window.openDatabase("phonegap100", "1.0","phonegap中文网",1024*1024*20);
if(db){
	console.log('数据库连接成功');
}else{
	console.log('数据库连接失败');
}
//2.执行transaction
db.transaction(function(tx){
	//tx.executeSql
	tx.executeSql("CREATE TABLE test (id int UNIQUE, name TEXT, age int)");	
})

//插入数据
db.transaction(function(tx){
	//tx.executeSql	
	//四个参数  第一个 sql语句  第二个 sql参数  第三个 成功的回调函数 第四个 失败的回调函数
	tx.executeSql("insert into test(id,name,age) values(1,'张三',20)");		
	tx.executeSql("insert into test(id,name,age) values(2,'李四',25)");
	
	tx.executeSql("insert into test(id,name,age) values(?,?,?)",[3,'赵四',15],null,null);
	
/*	tx.executeSql("insert into test(name,age) values('赵四666',25)",[],function(tx,rel){
		if(rel.rowsAffected>0){	
			//新增成功
			console.log('成功的增加一条数据');
			console.log('这条数据的id'+rel.insertId);
		}		
	},function(){
		alert('失败');
	});
	*/
})
//更新数据
db.transaction(function(tx){
	//tx.executeSql	
	//四个参数  第一个 sql语句  第二个 sql参数  第三个 成功的回调函数 第四个 失败的回调函数
	//tx.executeSql("insert into test(id,name,age) values(1,'张三',20)");		
	//tx.executeSql("insert into test(id,name,age) values(2,'李四',25)");
	
	//tx.executeSql("update test set name=?,age=? where id=1",['张三1',50],null,null);
	
	//tx.executeSql("update test set name='张三22',age=60 where id=1");
})

//删除数据
db.transaction(function(tx){
	//tx.executeSql	
	//四个参数  第一个 sql语句  第二个 sql参数  第三个 成功的回调函数 第四个 失败的回调函数
	//tx.executeSql("insert into test(id,name,age) values(1,'张三',20)");		
	//tx.executeSql("insert into test(id,name,age) values(2,'李四',25)");
	
	//tx.executeSql("update test set name=?,age=? where id=1",['张三1',50],null,null);
	
	//tx.executeSql("delete from test where id=1");
})

//查询数据
db.transaction(function(tx){
	//tx.executeSql	
	//四个参数  第一个 sql语句  第二个 sql参数  第三个 成功的回调函数 第四个 失败的回调函数
	//tx.executeSql("insert into test(id,name,age) values(1,'张三',20)");		
	//tx.executeSql("insert into test(id,name,age) values(2,'李四',25)");
	
	//tx.executeSql("update test set name=?,age=? where id=1",['张三1',50],null,null);
	
	tx.executeSql("select * from test",[],function(tx,rel){
		for(var i=0;i<rel.rows.length;i++){
			document.write('姓名:'+rel.rows.item(i)['name']+'年龄:'+rel.rows.item(i)['age']+'<br>');
		}
		
	},function(){
		alert('失败');
	});
})

</script>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: