Как использовать подготовленные инструкции в SQlite в Android?
Как использовать подготовленные инструкции в SQlite в Android?
Ответ 1
Я все время использую готовые заявления в Android, это довольно просто:
SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement stmt = db.compileStatement("SELECT * FROM Country WHERE code = ?");
stmt.bindString(1, "US");
stmt.execute();
Ответ 2
Для подготовленных операторов SQLite в Android есть SQLiteStatement. Подготовленные заявления помогают ускорить работу (особенно для операторов, которые нужно выполнять несколько раз), а также помогают избежать атак на атаку. См. эту статью для общего обсуждения подготовленных заявлений.
SQLiteStatement
предназначен для использования с операторами SQL, которые не возвращают несколько значений. (Это означает, что вы не будете использовать их для большинства запросов.) Ниже приведены некоторые примеры:
Создать таблицу
String sql = "CREATE TABLE table_name (column_1 INTEGER PRIMARY KEY, column_2 TEXT)";
SQLiteStatement stmt = db.compileStatement(sql);
stmt.execute();
Метод execute()
не возвращает значение, поэтому его следует использовать с CREATE и DROP, но не предназначено для использования с SELECT, INSERT, DELETE и UPDATE, потому что они возвращают значения. (Но см. этот вопрос.)
Вставить значения
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (57, 'hello')";
SQLiteStatement statement = db.compileStatement(sql);
long rowId = statement.executeInsert();
Обратите внимание, что используется executeInsert()
, а не execute()
. Конечно, вы не хотели бы всегда вводить одни и те же вещи в каждой строке. Для этого вы можете использовать привязки .
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); // These match to the two question marks in the sql string
statement.bindString(2, stringValue);
long rowId = statement.executeInsert();
Обычно вы используете подготовленные инструкции, когда хотите быстро повторять что-то (например, INSERT) много раз. Подготовленный оператор делает так, что SQL-запрос не должен анализироваться и скомпилироваться каждый раз. Вы можете ускорить работу, используя транзакции. Это позволяет сразу применить все изменения. Вот пример:
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();
}
Ознакомьтесь с этими ссылками для получения более подробной информации о транзакциях и ускорения вставки баз данных.
- Atomic Commit В SQLite (подробное объяснение, перейдите к части 3)
- транзакции базы данных
- Пример добавления и обновления Android SQLite
- Пример транзакции Android SQLite с выражением, подготовленным INSERT
- Перезагрузите свои вставки SQLite на Android
- fooobar.com/questions/67954/...
Обновить строки
Это основной пример. Вы также можете применить концепции из раздела выше.
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()
также может использоваться для операторов DELETE и был введен в API 11. См. этот вопрос & A.
Query
Обычно, когда вы запускаете запрос, вы хотите вернуть курсор с большим количеством строк. Впрочем, это не то, что SQLiteStatement
. Вы не запускаете запрос с ним, если только вам нужен простой результат, например количество строк в базе данных, которое вы можете сделать с помощью simpleQueryForLong()
String sql = "SELECT COUNT(*) FROM table_name";
SQLiteStatement statement = db.compileStatement(sql);
long result = statement.simpleQueryForLong();
Обычно вы запускаете метод query()
SQLiteDatabase, чтобы получить курсор.
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);
Подробнее о запросах см. .
Ответ 3
Если вы хотите, чтобы курсор возвращался, вы можете подумать примерно так:
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"));
Смотрите этот фрагмент Genscripts, если вы хотите получить более полную версию. Обратите внимание, что это параметризованный SQL-запрос, поэтому, по сути, это подготовленный оператор.
Ответ 4
Пример jasonhudgins не будет работать. Вы не можете выполнить запрос с помощью stmt.execute()
и вернуть значение (или Cursor
).
Вы можете только прекомпилировать операторы, которые либо не возвращают никакие строки вообще (например, вставку, либо создают инструкцию таблицы), либо одну строку и столбец (и используют simpleQueryForLong()
или simpleQueryForString()
).
Ответ 5
Чтобы получить курсор, вы не можете использовать compiledStatement. Однако, если вы хотите использовать полностью подготовленный оператор SQL, я рекомендую адаптировать метод jbaez... Используя db.rawQuery()
вместо db.query()
.