android - 如何在 Android 的 SQlite 中使用准备好的语句?

标签 android sqlite prepared-statement

如何在 Android 的 SQlite 中使用准备好的语句?

最佳答案

对于 Android 中准备好的 SQLite 语句,有 SQLiteStatement .准备好的语句可以帮助您提高性能(尤其是对于需要多次执行的语句),还可以帮助避免注入(inject)攻击。见 this article有关准备好的陈述的一般性讨论。

SQLiteStatement 用于不返回多个值的 SQL 语句。 (这意味着您不会将它们用于大多数查询。)以下是一些示例:

Create a table

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 一起使用,因为这些返回值。 (但见 this question。)

Insert values

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

请注意 executeInsert()使用方法而不是 execute()。当然,您不希望总是在每一行中输入相同的内容。为此,您可以使用 bindings .

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();

当您想要多次快速重复某事(如 INSERT)时,通常会使用准备好的语句。准备好的语句使得 SQL 语句不必每次都被解析和编译。您可以使用 transactions 进一步加快速度。 .这允许一次应用所有更改。这是一个例子:

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();
}

查看这些链接以获取有关事务和加速数据库插入的更多信息。

Update rows

这是一个基本示例。您也可以应用上一节中的概念。

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();

Delete rows

executeUpdateDelete() 方法也可用于 DELETE 语句,并在 API 11 中引入。See this Q&A .

这是一个例子。

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();
}

Query

通常,当您运行查询时,您希望返回包含大量行的游标。不过,这不是 SQLiteStatement 的用途。除非您只需要一个简单的结果,例如数据库中的行数,否则您不会使用它运行查询,您可以使用 simpleQueryForLong()

String sql = "SELECT COUNT(*) FROM table_name";
SQLiteStatement statement = db.compileStatement(sql);
long result = statement.simpleQueryForLong();

通常你会运行 SQLiteDatabasequery() 方法获取光标。

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);

this answer了解有关查询的更多详细信息。

关于android - 如何在 Android 的 SQlite 中使用准备好的语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/433392/

相关文章:

android - 如何在私有(private) channel 的google play中添加应用程序

python - 需要帮助迭代 SQLite DB 中的每一行以呈现为 html 模板

java - sqlite 安卓 : table not found

mySQL 多行搜索

android - 如何将具有 ACTION_SEND Intent 的 url 中的图像发送到其他应用程序?

Android Material 设计 - Material Motion

android - 多段线上的居中标记

SQLite 查找最近或下一个 ROWID 的 ROWID

postgresql - 如何从已执行的准备语句中获取 $1 参数的值(在使用 current_query() 的触发器内)

php - 如何准备具有动态数量参数的语句?