Как использовать подготовленные заявления в SQLite в Android?

голоса
85

Как использовать подготовленные заявления в SQLite в Android?

Задан 11/01/2009 в 19:38
источник пользователем
На других языках...                            


5 ответов

голоса
134

Для подготовленных 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 IGNORE, DELETE и UPDATE , потому что эти возвращаемые значения. (Но увидеть этот вопрос .)

значения вставки

String sql = "INSERT IGNORE  INTO table_name (column_1, column_2) VALUES (57, 'hello')";
SQLiteStatement statement = db.compileStatement(sql);
long rowId = statement.executeInsert();

Следует отметить , что executeInsert()метод используется вместо execute(). Конечно, вы не хотели бы, чтобы всегда вводить одни и те же вещи , в каждой строке. Для этого вы можете использовать привязки .

String sql = "INSERT IGNORE  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();

Обычно вы используете подготовленные заявления , когда вы хотите быстро повторить что - то (как Вкладышем ИГНОРИРУЙТЕ) много раз. Подготовленное заявление делает это так , что SQL оператор не должен быть разобран и скомпилирован каждый раз. Вы можете ускорить процесс, даже больше с помощью операций . Это позволяет все изменения будут применены сразу. Вот пример:

String stringValue = "hello";
try {

    db.beginTransaction();
    String sql = "INSERT IGNORE  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();
}

Проверьте эти ссылки на какой-то более хорошей информации о сделках и ускоряя вставки базы данных.

строки обновления

Это простой пример. Кроме того, можно применять понятия из предыдущего раздела.

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()также может быть использован для ВЕЬЕТЕ и был введен в API 11. Смотрите этот Q & A .

запрос

Обычно при выполнении запроса, вы хотите , чтобы получить курсор назад с большим количеством строк. Это не то , что 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);

Смотрите этот ответ для больше деталей о запросах.

Ответил 22/04/2015 в 12:13
источник пользователем

голоса
25

Я использую подготовленные заявления в Android все время, это довольно просто:

SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement stmt = db.compileStatement("SELECT * FROM Country WHERE code = ?");
stmt.bindString(1, "US");
stmt.execute();
Ответил 12/01/2009 в 18:12
источник пользователем

голоса
21

Если вы хотите курсор на возвращение, то вы могли бы рассмотреть что-то вроде этого:

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, так что по сути, это подготовленное заявление.

Ответил 03/09/2010 в 15:55
источник пользователем

голоса
9

jasonhudgins пример не будет работать. Вы не можете выполнить запрос с stmt.execute()и получить значение (или Cursor) обратно.

Вы можете только прекомпиляции заявления, либо возвращает ни одной строки на всех (например, вставки, или создать таблицу заявление) или одну строку и столбец, (и использовать simpleQueryForLong()или simpleQueryForString()).

Ответил 06/06/2010 в 10:15
источник пользователем

голоса
1

Для того, чтобы получить курсор, вы не можете использовать compiledStatement. Тем не менее, если вы хотите использовать полный подготовленный оператор SQL, я рекомендую адаптацию метода jbaez в ... Использование db.rawQuery()вместо db.query().

Ответил 14/10/2010 в 19:58
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more