1. 程式人生 > >前端儲存之websql

前端儲存之websql

最近公司系統需要做一個app,經過調查研究,決定用html5 + phonegap技術來開發,一方面對於html5技術已經很熟悉(雖然之前android也有所研究,但是還是在html5方面傾注精力更多),而且公司的專案pc端本身就是B/S的,移植到手機端比較容易,研發成本也比較低;另外基於html5技術的開發,可以做到跨平臺,同時跑在android 和iOS兩大系統沒有問題。

app需要用到一些前端儲存,而且是關係型資料儲存的需求,當然用phonegap的機制,可以呼叫native的儲存,不過實現起來很麻煩;所以就考慮用html5的前端離線儲存,前端離線儲存目前支援 Cookie、localStorage、sessionStorage、IndexedDB、Web SQL Database以及FileSystem.

Cookie就不用說,用起來超級麻煩,而且限制極大;不適合。
sessionStorage其實算不上離線儲存,因為網頁關閉了,儲存就會丟棄。
localStorage可以做key value 的儲存,對於需要有些關係處理的資料,需要自己做邏輯處理,比較麻煩。
IndexedDB其實就是前段的nosql資料庫。

比較靠譜的是websql和IndexedDB,不過由於需要關係資料庫的原因,選擇了websql,不過IndexedDB也是一個不錯的選擇,後面有機會寫寫這塊。

需要注意的是,HTML5已經會放棄Web SQL Database

放棄的原因如下:

This document was on the W3C Recommendation track but specification work has stopped. The specification reached an impasse: all interested implementors have used the same SQL backend (Sqlite), but we need multiple independent implementations to proceed along a standardisation path.
大概意思是:
該檔案是W3C推薦標準,但規範的制定工作已經停止。該規範陷入僵局:所有感興趣的實現者都使用了相同的SQL後端(SQLite的),但我們需要多個獨立的實現沿著規範化的路徑進行。
翻譯參考:

http://www.zhihu.com/question/41951041
有關標準參考: https://www.w3.org/TR/webdatabase/

關於這一點,我覺得一方面我們的app是驗證型的,並不是正式需要釋出的,所以選擇websql沒有什麼後顧之憂,另外,我覺得,瀏覽器廠商就算以後不再改進websql,把現有的websql功能去掉的可能性不是很大,而目前的功能也滿足需求了。

websql是很久的技術了,很早關注過,不過一直沒用,最近想用,搜尋了下,網上關於websql的文章已經很多,但是發現大部分文章都是抄來抄去的;可能很多東西大家也沒有試驗,就抄襲了過來;正好自己用到了相關的知識,就來個比較全面的整理。

如果你掌握過mysql,orancle,mssql等關係型資料庫,對於websql的理解還是比較容易的。

websql的關鍵技術點分為:

  1. 測試瀏覽器支援
  2. 建立資料庫
  3. 建立表格
  4. 插入資料等

    用到的幾個核心方法:

  5. openDatabase openDatabaseSycn 建立資料庫

  6. transaction起事務
  7. executeSql執行sql語句

測試瀏覽器支援

if(window.openDatabase){
console.log(“瀏覽器支援DataBase”);
}

建立資料庫

在window物件上,有一個openDatabase方法,可以建立資料庫,參考標準

Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);

  var test_db = window.openDatabase('test', '1.0', 'Test DB', 2 * 1024 * 1024);

openDatabase共四個引數,第一個引數資料庫名,第二個引數資料庫版本號,第三個描述,第四個估計大小,四個引數都必須輸入,但是最後一個引數可以輸入null,最終建立的物件如下:

WebSQL DataBase物件

可以看出db物件上面有changeVersion方法可以改變版本號,.version可以獲取版本號,transaction方法可以起事務,readTransaction方法起一個只讀的事務,參考標準

For the transaction() method, the mode must be read/write. For the readTransaction() method, the mode must be read-only.

其實標準裡面還有個openDatabaseSync方法,但是測試發現並沒有實現【測試chrome,safari】

openDatabase還有第5個引數creationCallback,可選擇的;但是測試發現如果加入了callback引數,建立的database的版本號就總是為空。

起資料庫事務

從前面的圖片中可以看到,有兩個事務的方法,一個transaction,一個readTransaction, 兩個方法均是非同步的,通過傳遞一個callback來執行後續操作

  test_db.transaction(function(tx){console.log(tx);})

Transaction物件

回撥函式會被傳入一個SQLTransaction物件,該物件可以執行executeSql方法。

執行SQL語句

執行sql語句和一般的關係型資料庫類似,不同的是,websql支援的資料型別 函式 等都相當有限。
executeSql支援四個引數,sql語句,sql引數,成功回撥函式,錯誤回撥函式,回撥函式第一個引數是transaction,第二個是執行結果;錯誤回撥函式第一個引數是transaction,第二個引數是錯誤。

建立一個數據表

var success = function(tx,results){
   console.log(results);
 };
 var error = function(tx, err){
    console.log(error);
 };
var sql = 'CREATE TABLE foo (id unique, text)';
test_db.transaction(function(tx){
    tx.executeSql(sql,[],success,error);
});

可以看出不需要指定欄位的型別,unique表示唯一,其實也可以指定型別,但是測試發現其實指定了也沒什麼用,如下指定todo型別為TEXT,added_on 為DATETIME,但是在後面可以插入任意型別資料,不起約束左右;另外看有的文章說不支援自增長,測試發現是可以的。【只是在pc上測試了chrome和safari,未測試移動端的情況】【後來在移動端測試也可以】

 tx.executeSql("CREATE TABLE IF NOT EXISTS " +
                  "todo(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME)", [],success,error);

插入資料

test_db.transaction(function(tx){
    tx.executeSql('INSERT INTO foo (id, text) VALUES (1, "test")',[],success,error);
});

查詢資料

tx.executeSql('SELECT * FROM foo', [], function (tx, results) {
  var len = results.rows.length, i;
  for (i = 0; i < len; i++) {
    alert(results.rows.item(i).text);
  }
});

查詢的資料格式標準如下,通過rows.item()可以訪問資料

interface SQLResultSet {
readonly attribute long insertId;
readonly attribute long rowsAffected;
readonly attribute SQLResultSetRowList rows;
};
參考: https://www.w3.org/TR/webdatabase/#sqlresultset

刪除資料


 test_db.transaction(function(tx){
    tx.executeSql("DELETE FROM todo foo ID=?", [id],success,error);
    });

支援瀏覽器情況

firefox 不支援,IE edge 一貫作風不支援; chrome Safari支援,移動端android iOS支援的都很不錯,
具體參考 http://caniuse.com/#feat=sql-storage

使用場景

有本地儲存需求的應用,比如開發一個本地儲存的web端遊戲;
如果開發基於html5技術的手機app,也可以考慮用websql做本地儲存,不過由於前面提到的原因,如果你的app考慮長遠發展,建議使用IndexedDB。

參考文件