12

我正在开发一个 Android Cordova/Phonegap 应用程序,我想在其中使用 SQLite 数据库。我使用了官方文档中的示例。

// Wait for device API libraries to load
//
document.addEventListener("deviceready", onDeviceReady, false);

// Populate the database
//
function populateDB(tx) {
    tx.executeSql('DROP TABLE IF EXISTS DEMO');
    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")');
}

// Query the database
//
function queryDB(tx) {
    tx.executeSql('SELECT * FROM DEMO', [], querySuccess, errorCB);
}

// Query the success callback
//
function querySuccess(tx, results) {
    var len = results.rows.length;
    console.log("DEMO 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);
    }
}

// Transaction error callback
//
function errorCB(err) {
    console.log("Error processing SQL: "+err.code);
}

// Transaction success callback
//
function successCB() {
    var db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
    db.transaction(queryDB, errorCB);
}

// device APIs are available
//
function onDeviceReady() {
    var db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
    db.transaction(populateDB, errorCB, successCB);
}

尽管这似乎可行(数据库的创建和填充没有错误,并且我通过查询返回写入的数据),但我想知道数据库是如何存储在我的设备上的。对于调试,我使用的是 Android 4.1.1 的硬件手机。

该数据库位于/data/data/<myapppackage>/app_database/file__0/0000000000000001.db. 现在我想导出数据库并在我的电脑上使用 SQLiteManager 手动分析它,但似乎更改没有写入 db 文件。

但是,在检查目录时,/data/data/<myapppackage>/app_database/file__0/我发现了两个临时文件0000000000000001.db-shm0000000000000001.db-wal,每次执行数据库操作时都会更改其时间戳,但不会更改 db 文件本身。

我的问题是,为什么从未将更改写入持久数据库文件?似乎没有办法关闭与 phonegap 的数据库连接,甚至手动终止应用程序也不会将更改写入 .db 文件。我不确定我做错了什么。

有人在这里看到问题吗?

4

3 回答 3

11
tx.executeSql('DROP TABLE IF EXISTS DEMO');

每次启动 PhoneGap 移动应用程序时,上面的这一行都会删除名为 DEMO 的表

我只是想告诉你我喜欢你的代码。它为任何人的 PhoneGap 或 Cordova 应用程序提供了关于“做什么”的非常好的线索。它将极大地帮助任何第一次进入 SQLite 世界的人。

与在 GitHub 上的 Cordova/PhoneGap SQLite 插件官方网站上编写的代码相比,您的代码非常清晰易读和理解。

我的朋友也是一家公司的CTO,对SQLite有丰富的经验,告诉我不需要手动关闭SQLite数据库连接,也非常推荐SQLite。

对于其他任何寻找 SQLite 以获取 PhoneGap/Cordova 信息​​的人 -

假设您有一个名为 mytable 的表,并且想要存储值“beautiful”和“dolphin”

当你想在移动设备的 SQLite 上执行操作时,例如平板电脑或手机,记得这样调用

在您的源代码中包含以下内容

function insertNewLine(tx) 
{
   tx.executeSql("INSERT INTO mytable (word, meaning) VALUES (?,?)", [ var1 , var2 ]);
}

并将“美丽”存储在 var1 中,将“海豚”存储在 var2 中,

执行以下语句以执行 SQL 插入语句,然后保存在设备中。

db.transaction(insertNewLine);   

不要直接调用 insertNewLine(tx)

不要直接调用 tx.executeSql( /* SQL INSERT STATEMENT */ ); 在你的 JavaScript 源代码中

并且不要将值直接包含在 SQL 查询语句中,然后运行包含要存储在数据库中的值的 SQL 语句。

换句话说,以下是不正确的

tx.executeSql('INSERT INTO mytable (word, meaning) values (beautiful, dolphin)');

以上是不正确的,因为您要存储的值“美丽”和“海豚”包含在 SQL 语句中。他们应该是分开的。

以下是运行INSERT SQL的正确方法

tx.executeSql("INSERT INTO mytable (word, meaning) VALUES (?,?)", [ var1 , var2 ]);
 // Notice that the values you want to store, beautiful and dolphin
 // are separate from the SQL INSERT INTO statement

然后通过在您的 JavaScript 代码中包含以下内容来执行整个数据库事务

db.transaction(insertNewLine);

不是下面的代码

tx.executeSql("INSERT....."); // this will not save your values onto the device

也不是下面的代码

insertNewLine(tx); // this will not save your values onto the device either.  

并使用 SELECT SQL 语句,有以下代码

// Get all lines in the table
//
function viewthelastglory(tx)  
{
    tx.executeSql( 'SELECT * FROM CUSTOMTABLE', [], querySuccess, errorcode );
}

// Deal with the lines 
//
function querySuccess(tx, results) 
{
   var len = results.rows.length; var  queryresult = "all entries ";

   for (var i = 0 ; i < len ; i++)
   {
       queryresult =  queryresult +  

       " Row - " + i + 
       " Word - " + results.rows.item(i).word + 
       " Meaning - " + results.rows.item(i).meaning;
   }

// and now, you can use the queryresult variable to use the values   
}

function errorcode(errorhaha) 
{
    alert("Error Code " + errorhaha.code + " Error Message " + errorhaha.message);
}

然后,执行数据库事务

db.transaction(viewthelastglory);

如果您尝试从 SQLite、WebSQL 和 IndexedDB 中选择一个,请记住我在 stackoverflow 上搜索了一段时间并了解到

  • 没有人喜欢 IndexedDB 因为它的复杂性
  • IndexedDB 与许多类型和版本的移动操作系统不兼容
  • W3C 已弃用 WebSQL
  • WebSQL 返回 673K​​ 结果,但 SQLite 返回 1800K 结果。IndexedDB 在 Google 上返回 300K 结果
  • 在 IndexedDB、SQLite 和 WebSQL 中,只有 SQLite 有官方网站。

当您在 Cordova 项目目录中时,命令行中的以下命令会将 SQLite 插件安装到您的 Cordova 项目中

cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin
于 2014-08-27T03:22:29.320 回答
0

解决方案是:使用模拟器而不是物理设备调试您的应用程序。

emulator使用而不是物理设备运行您的应用程序。您将database/data/data/YOUR_PACKAGE_NAME/app_database/. 您可以文件pulldatabase浏览表和数据。

于 2013-11-01T05:22:21.613 回答
0

WAL 模式下,任何更改都会写入-wal文件;在检查点完成之前,数据库文件本身不会更新。

如果有-wal文件,您也必须复制它。

于 2014-08-04T09:30:49.960 回答