web-dev-qa-db-ja.com

AndroidおよびPhonegapを使用したSQLiteデータベースのストレージ

SQLiteデータベースを使用したいAndroid Cordova/Phonegapアプリを開発しています。公式の例を使用しました ドキュメント

// 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を使用してPCで手動で分析したかったのですが、変更がdbファイルに書き込まれていないようです。

ただし、ディレクトリ/data/data/<myapppackage>/app_database/file__0/を調べると、2つの一時ファイル0000000000000001.db-shm0000000000000001.db-walが見つかりました。これらのタイムスタンプは、データベース操作を実行するたびに変更されますが、dbファイル自体は変更されません。

私の質問は、なぜ変更が永続データベースファイルに書き込まれないのですか? phonegapを使用してデータベース接続を閉じる方法はないようです。また、アプリを手動で強制終了しても、変更は.dbファイルに書き込まれません。何を間違えたのかわかりません。

ここで問題を見ている人はいますか?

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

上記の行は、PhoneGapモバイルアプリケーションを起動するたびにDEMOという名前のテーブルを削除します

そして、私はあなたのコードが大好きだと言いたかっただけです。これは、誰のPhoneGapまたはCordovaアプリケーションの「何をすべきか」についての非常に良い手がかりを与えます。これは、SQLiteの世界に初めて参入する人を大いに助けます。

GitHubのCordova/PhoneGap SQLiteプラグインの公式ウェブサイトに書かれているコードと比較して、コードは非常に読みやすく、理解しやすいものです。

会社のCTOを兼務しており、SQLiteの経験が豊富な友人から、SQLiteデータベース接続を手動で閉じる必要はないと言われ、SQLiteを強くお勧めしました。

そして、PhoneGap/Cordova情報のSQLiteを探している他の人のために-

Mytableという名前のテーブルがあり、「beautiful」と「dolphin」の値を格納するとします。

タブレットや電話などのモバイルデバイスのSQLiteで操作を実行する場合は、このように呼び出すことを忘れないでください

ソースコードに次のものを含めます

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

var1内に「beautiful」を格納し、var2内に「dolphin」を格納します。

sQLの挿入ステートメントを実行してデバイス内に保存するには、次のステートメントを実行します。

db.transaction(insertNewLine);   

しないでください insertNewLine(tx)を直接呼び出します

しないでください tx.executeSql(/ * SQL INSERT STATEMENT * /);を直接呼び出します。 JavaScriptソースコードで

しないでください値をSQLクエリステートメントに直接含めてから、データベースに格納する値を含むSQLステートメントを実行します。

言い換えれば、以下は不正解

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

保存する値「beautiful」と「dolphin」がSQLステートメントに含まれているため、上記は正しくありません。それらは分離する必要があります。

以下は、INSERTSQLを実行する正しい方法です。

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から1つを選択しようとしている場合は、しばらくの間stackoverflowを検索して、それを学んだことを覚えておいてください。

  • IndexedDBは複雑であるため、誰も好きではありません
  • IndexedDBは、モバイルOSの多くのタイプおよびバージョンと互換性がありません
  • WebSQLはW3Cによって非推奨になりました
  • WebSQLは673Kの結果を返しますが、SQLiteは1800Kの結果を返します。 IndexedDBはGoogleで30万件の結果を返します
  • IndexedDB、SQLite、WebSQLの中で、公式Webサイトを持っているのはSQLiteだけです。

Cordovaプロジェクトのディレクトリにいるときにコマンドラインで次のコマンドを実行すると、SQLiteプラグインがCordovaプロジェクトにインストールされます。

cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin
11
KershawRocks

解決策は次のとおりです:物理デバイスの代わりにエミュレーターを使用してアプリをデバッグします。

物理デバイスの代わりにemulatorを使用してアプリを実行します。 databaseファイルは/data/data/YOUR_PACKAGE_NAME/app_database/にあります。 pulldatabaseファイルを作成して、テーブルとデータを参照できます。

0
Lekhnath

WALモード では、変更はすべて-walファイルに書き込まれます。 チェックポイント が実行されるまで、データベースファイル自体は更新されません。

-walファイルがある場合は、それもコピーする必要があります。

0
CL.