Bagaimana cara menggunakan pernyataan yang disiapkan di SQlite di Android?
Bagaimana cara menggunakan pernyataan yang disiapkan di SQlite di Android?
Jawaban:
Saya menggunakan pernyataan yang sudah disiapkan di Android sepanjang waktu, ini cukup sederhana:
SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement stmt = db.compileStatement("INSERT INTO Country (code) VALUES (?)");
stmt.bindString(1, "US");
stmt.executeInsert();
SQLiteStatement.bindXXX()
memiliki indeks berbasis 1, bukan berbasis 0 seperti yang lainnya.
Untuk pernyataan SQLite yang disiapkan di Android ada SQLiteStatement . Pernyataan yang telah disiapkan membantu Anda mempercepat kinerja (terutama untuk pernyataan yang perlu dijalankan beberapa kali) dan juga membantu menghindari serangan injeksi. Lihat artikel ini untuk pembahasan umum tentang pernyataan yang disiapkan.
SQLiteStatement
dimaksudkan untuk digunakan dengan pernyataan SQL yang tidak mengembalikan banyak nilai. (Itu berarti Anda tidak akan menggunakannya untuk sebagian besar kueri.) Berikut adalah beberapa contohnya:
String sql = "CREATE TABLE table_name (column_1 INTEGER PRIMARY KEY, column_2 TEXT)";
SQLiteStatement stmt = db.compileStatement(sql);
stmt.execute();
The execute()
metode tidak mengembalikan nilai sehingga sangat tepat untuk digunakan dengan MENCIPTAKAN dan DROP tetapi tidak dimaksudkan untuk digunakan dengan SELECT, INSERT, DELETE, dan UPDATE karena kembali nilai-nilai tersebut. (Tapi lihat pertanyaan ini .)
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (57, 'hello')";
SQLiteStatement statement = db.compileStatement(sql);
long rowId = statement.executeInsert();
Perhatikan bahwa executeInsert()
metode yang digunakan daripada execute()
. Tentu saja, Anda tidak ingin selalu memasukkan hal yang sama di setiap baris. Untuk itu Anda bisa menggunakan binding .
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (?, ?)";
SQLiteStatement statement = db.compileStatement(sql);
int intValue = 57;
String stringValue = "hello";
statement.bindLong(1, intValue); // 1-based: matches first '?' in sql string
statement.bindString(2, stringValue); // matches second '?' in sql string
long rowId = statement.executeInsert();
Biasanya Anda menggunakan pernyataan yang sudah disiapkan ketika Anda ingin dengan cepat mengulangi sesuatu (seperti INSERT) berkali-kali. Pernyataan yang disiapkan membuatnya sehingga pernyataan SQL tidak harus diurai dan dikompilasi setiap saat. Anda bahkan dapat mempercepat lebih banyak dengan menggunakan transaksi . Ini memungkinkan semua perubahan diterapkan sekaligus. Berikut ini contohnya:
String stringValue = "hello";
try {
db.beginTransaction();
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (?, ?)";
SQLiteStatement statement = db.compileStatement(sql);
for (int i = 0; i < 1000; i++) {
statement.clearBindings();
statement.bindLong(1, i);
statement.bindString(2, stringValue + i);
statement.executeInsert();
}
db.setTransactionSuccessful(); // This commits the transaction if there were no exceptions
} catch (Exception e) {
Log.w("Exception:", e);
} finally {
db.endTransaction();
}
Lihat tautan ini untuk beberapa info bagus lainnya tentang transaksi dan mempercepat penyisipan database.
Ini adalah contoh dasar. Anda juga dapat menerapkan konsep dari bagian di atas.
String sql = "UPDATE table_name SET column_2=? WHERE column_1=?";
SQLiteStatement statement = db.compileStatement(sql);
int id = 7;
String stringValue = "hi there";
statement.bindString(1, stringValue);
statement.bindLong(2, id);
int numberOfRowsAffected = statement.executeUpdateDelete();
The executeUpdateDelete()
Metode ini juga dapat digunakan untuk laporan DELETE dan diperkenalkan pada API 11. Lihat ini Q & A .
Berikut ini contohnya.
try {
db.beginTransaction();
String sql = "DELETE FROM " + table_name +
" WHERE " + column_1 + " = ?";
SQLiteStatement statement = db.compileStatement(sql);
for (Long id : words) {
statement.clearBindings();
statement.bindLong(1, id);
statement.executeUpdateDelete();
}
db.setTransactionSuccessful();
} catch (SQLException e) {
Log.w("Exception:", e);
} finally {
db.endTransaction();
}
Biasanya saat Anda menjalankan kueri, Anda ingin mendapatkan kursor kembali dengan banyak baris. Itu bukan untuk apa SQLiteStatement
. Anda tidak menjalankan kueri dengannya kecuali Anda hanya memerlukan hasil yang sederhana, seperti jumlah baris dalam database, yang dapat Anda lakukan dengansimpleQueryForLong()
String sql = "SELECT COUNT(*) FROM table_name";
SQLiteStatement statement = db.compileStatement(sql);
long result = statement.simpleQueryForLong();
Biasanya Anda akan menjalankan query()
metode SQLiteDatabase untuk mendapatkan kursor.
SQLiteDatabase db = dbHelper.getReadableDatabase();
String table = "table_name";
String[] columnsToReturn = { "column_1", "column_2" };
String selection = "column_1 =?";
String[] selectionArgs = { someValue }; // matched to "?" in selection
Cursor dbCursor = db.query(table, columnsToReturn, selection, selectionArgs, null, null, null);
Lihat jawaban ini untuk detail yang lebih baik tentang kueri.
clearBindings()
tidak hanya mengaturnya ke null
(lihat kode sumber ). Saya melihatnya sebagai membersihkan status sehingga tidak ada yang mempengaruhinya dari loop sebelumnya. Mungkin itu tidak perlu. Saya akan senang untuk seseorang yang tahu untuk berkomentar.
Jika Anda ingin kursor kembali, Anda dapat mempertimbangkan sesuatu seperti ini:
SQLiteDatabase db = dbHelper.getWritableDatabase();
public Cursor fetchByCountryCode(String strCountryCode)
{
/**
* SELECT * FROM Country
* WHERE code = US
*/
return cursor = db.query(true,
"Country", /**< Table name. */
null, /**< All the fields that you want the
cursor to contain; null means all.*/
"code=?", /**< WHERE statement without the WHERE clause. */
new String[] { strCountryCode }, /**< Selection arguments. */
null, null, null, null);
}
/** Fill a cursor with the results. */
Cursor c = fetchByCountryCode("US");
/** Retrieve data from the fields. */
String strCountryCode = c.getString(cursor.getColumnIndex("code"));
/** Assuming that you have a field/column with the name "country_name" */
String strCountryName = c.getString(cursor.getColumnIndex("country_name"));
Lihat cuplikan Genskrip ini jika Anda ingin yang lebih lengkap. Perhatikan bahwa ini adalah kueri SQL berparameter, jadi pada dasarnya, ini adalah pernyataan yang disiapkan.
Contoh jasonhudgins tidak akan bekerja. Anda tidak dapat menjalankan kueri dengan stmt.execute()
dan mendapatkan nilai (atau a Cursor
) kembali.
Anda hanya dapat mengkompilasi pernyataan yang tidak mengembalikan baris sama sekali (seperti menyisipkan, atau membuat pernyataan tabel) atau satu baris dan kolom, (dan menggunakan simpleQueryForLong()
atau simpleQueryForString()
).