Android'de SQlite'de hazırlanmış ifadeleri nasıl kullanırım?
Android'de SQlite'de hazırlanmış ifadeleri nasıl kullanırım?
Yanıtlar:
Android'de her zaman hazırlanmış ifadeler kullanıyorum, oldukça basit:
SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement stmt = db.compileStatement("INSERT INTO Country (code) VALUES (?)");
stmt.bindString(1, "US");
stmt.executeInsert();
SQLiteStatement.bindXXX()
En çok olduğu gibi 0 tabanlı değil, 1 tabanlı bir dizine sahip olduğuna dikkat edin.
Android'de hazırlanan SQLite deyimleri için SQLiteStatement vardır . Hazırlanan ifadeler performansı hızlandırmanıza yardımcı olur (özellikle birden çok kez yürütülmesi gereken ifadeler için) ve ayrıca enjeksiyon saldırılarına karşı önlemeye yardımcı olur. Hazırlanmış ifadeler hakkında genel bir tartışma için bu makaleye bakın .
SQLiteStatement
birden çok değer döndürmeyen SQL ifadeleriyle kullanılması amaçlanmıştır. (Bu, çoğu sorgu için onları kullanmayacağınız anlamına gelir.) Aşağıda bazı örnekler verilmiştir:
String sql = "CREATE TABLE table_name (column_1 INTEGER PRIMARY KEY, column_2 TEXT)";
SQLiteStatement stmt = db.compileStatement(sql);
stmt.execute();
execute()
CREATE ve bırak ile kullanmak için uygun olan, ancak DELETE SELECT, INSERT ile kullanılması amaçlanan ve UPDATE bu değerleri, çünkü böylece yöntemi bir değer döndürmez. (Ama bu soruya bakın .)
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (57, 'hello')";
SQLiteStatement statement = db.compileStatement(sql);
long rowId = statement.executeInsert();
executeInsert()
Yöntemin yerine kullanıldığını unutmayın execute()
. Elbette, her satıra her zaman aynı şeyleri girmek istemezsiniz. Bunun için bağlamaları kullanabilirsiniz .
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();
Genellikle bir şeyi (INSERT gibi) birçok kez hızlıca tekrarlamak istediğinizde hazırlanmış ifadeleri kullanırsınız. Hazırlanan ifade, SQL ifadesinin her seferinde ayrıştırılması ve derlenmesi gerekmemesini sağlar. İşlemleri kullanarak işleri daha da hızlandırabilirsiniz . Bu, tüm değişikliklerin aynı anda uygulanmasına izin verir. İşte bir örnek:
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();
}
İşlemler ve veri tabanı girişlerini hızlandırmak hakkında daha iyi bilgiler için bu bağlantılara göz atın.
Bu temel bir örnektir. Yukarıdaki bölümdeki kavramları da uygulayabilirsiniz.
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();
executeUpdateDelete()
Yöntem ayrıca, DELETE tablolar için de kullanılabilir ve API 11'de tanıtılan See Bu soru-cevap .
İşte bir örnek.
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();
}
Normalde bir sorgu çalıştırdığınızda, çok sayıda satır içeren bir imleci geri almak istersiniz. Yine de bunun SQLiteStatement
için değil . Veritabanındaki satır sayısı gibi yalnızca basit bir sonuca ihtiyacınız olmadığı sürece onunla bir sorgu çalıştırmazsınız.simpleQueryForLong()
String sql = "SELECT COUNT(*) FROM table_name";
SQLiteStatement statement = db.compileStatement(sql);
long result = statement.simpleQueryForLong();
Genellikle bir imleç almak için SQLiteDatabasequery()
yöntemini çalıştırırsınız .
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);
Sorgular hakkında daha ayrıntılı bilgi için bu yanıta bakın .
clearBindings()
yalnızca onları ayarlamadığını söyledi null
( kaynak koduna bakın ). Ben buna durumu temizliyor olarak bakıyorum, böylece önceki döngüden hiçbir şey onu etkilemiyor. Belki de bu gerekli değildir. Yorum yapmayı bilen biri için mutlu olurum.
Dönüşte bir imleç istiyorsanız, bunun gibi bir şey düşünebilirsiniz:
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"));
Daha eksiksiz bir tane istiyorsanız, bu pasaj Genscripts'e bakın . Bunun parametreleştirilmiş bir SQL sorgusu olduğuna dikkat edin, bu nedenle özünde hazırlanmış bir ifadedir.
jasonhudgins örneği işe yaramayacak. İle bir sorgu çalıştırıp bir stmt.execute()
değer (veya a Cursor
) geri alamazsınız .
Yalnızca hiç satır döndürmeyen (bir ekleme veya tablo deyimi oluşturma gibi) veya tek bir satır ve sütun (ve simpleQueryForLong()
veya kullanın simpleQueryForString()
) ifadelerini önceden derleyebilirsiniz .