Làm cách nào để sử dụng các câu lệnh đã soạn sẵn trong SQlite trong Android?
Làm cách nào để sử dụng các câu lệnh đã soạn sẵn trong SQlite trong Android?
Câu trả lời:
Tôi sử dụng các câu lệnh chuẩn bị sẵn trong Android mọi lúc, nó khá đơn giản:
SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement stmt = db.compileStatement("INSERT INTO Country (code) VALUES (?)");
stmt.bindString(1, "US");
stmt.executeInsert();
SQLiteStatement.bindXXX()
có chỉ mục dựa trên 1, không dựa trên 0 như hầu hết các chỉ số.
Đối với các câu lệnh SQLite đã chuẩn bị sẵn trong Android, có SQLiteStatement . Các câu lệnh chuẩn bị sẵn giúp bạn tăng tốc hiệu suất (đặc biệt đối với các câu lệnh cần được thực thi nhiều lần) và cũng giúp tránh các cuộc tấn công chèn ép. Xem bài viết này để thảo luận chung về các tuyên bố đã chuẩn bị.
SQLiteStatement
được sử dụng với các câu lệnh SQL không trả về nhiều giá trị. (Điều đó có nghĩa là bạn sẽ không sử dụng chúng cho hầu hết các truy vấn.) Dưới đây là một số ví dụ:
String sql = "CREATE TABLE table_name (column_1 INTEGER PRIMARY KEY, column_2 TEXT)";
SQLiteStatement stmt = db.compileStatement(sql);
stmt.execute();
Các execute()
phương pháp không trả lại một giá trị nên rất thích hợp để sử dụng với CREATE và thả nhưng không nhằm phản ánh được sử dụng với SELECT, INSERT, DELETE, và UPDATE bởi vì những giá trị trả về. (Nhưng hãy xem câu hỏi này .)
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (57, 'hello')";
SQLiteStatement statement = db.compileStatement(sql);
long rowId = statement.executeInsert();
Lưu ý rằng executeInsert()
phương pháp được sử dụng hơn là execute()
. Tất nhiên, bạn sẽ không muốn luôn nhập những thứ giống nhau ở mọi hàng. Đối với điều đó, bạn có thể sử dụng các ràng buộc .
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();
Thông thường, bạn sử dụng các câu lệnh chuẩn bị sẵn khi bạn muốn lặp lại nhanh một điều gì đó (như CHÈN) nhiều lần. Câu lệnh đã chuẩn bị sẵn giúp cho câu lệnh SQL không phải được phân tích cú pháp và biên dịch mọi lúc. Bạn có thể tăng tốc mọi thứ hơn nữa bằng cách sử dụng các giao dịch . Điều này cho phép tất cả các thay đổi được áp dụng cùng một lúc. Đây là một ví dụ:
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();
}
Kiểm tra các liên kết này để biết thêm một số thông tin tốt về giao dịch và tăng tốc độ chèn cơ sở dữ liệu.
Đây là một ví dụ cơ bản. Bạn cũng có thể áp dụng các khái niệm từ phần trên.
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();
Các executeUpdateDelete()
phương pháp cũng có thể được sử dụng cho lệnh DELETE và đã được giới thiệu trong API 11. Xem Q & A .
Đây là một ví dụ.
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();
}
Thông thường khi bạn chạy một truy vấn, bạn muốn lấy lại một con trỏ với nhiều hàng. Tuy nhiên, đó không phải SQLiteStatement
là những gì dành cho. Bạn không chạy truy vấn với nó trừ khi bạn chỉ cần một kết quả đơn giản, chẳng hạn như số hàng trong cơ sở dữ liệu, bạn có thể thực hiện vớisimpleQueryForLong()
String sql = "SELECT COUNT(*) FROM table_name";
SQLiteStatement statement = db.compileStatement(sql);
long result = statement.simpleQueryForLong();
Thông thường bạn sẽ chạy query()
phương thức SQLiteDatabase để lấy con trỏ.
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);
Xem câu trả lời này để biết chi tiết tốt hơn về các truy vấn.
clearBindings()
không chỉ đặt chúng thành null
(xem mã nguồn ). Tôi xem nó như là xóa trạng thái để không có gì ảnh hưởng đến nó từ vòng lặp trước. Có lẽ điều đó không cần thiết. Tôi rất vui vì ai đó biết nhận xét.
Nếu bạn muốn con trỏ quay trở lại, thì bạn có thể xem xét điều gì đó như sau:
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"));
Xem đoạn mã này Genscripts trong trường hợp bạn muốn một đoạn hoàn chỉnh hơn. Lưu ý rằng đây là một truy vấn SQL được tham số hóa, vì vậy về bản chất, nó là một câu lệnh được chuẩn bị sẵn.
ví dụ jasonhudgins sẽ không hoạt động. Bạn không thể thực hiện truy vấn với stmt.execute()
và lấy lại giá trị (hoặc a Cursor
).
Bạn chỉ có thể biên dịch trước các câu lệnh trả về không có hàng nào (chẳng hạn như câu lệnh chèn hoặc tạo bảng) hoặc một hàng và cột duy nhất, (và sử dụng simpleQueryForLong()
hoặc simpleQueryForString()
).