当前位置:  开发笔记 > 前端 > 正文

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

如何解决《如何在Android中的SQlite中使用预准备语句?》经验,为你挑选了4个好方法。

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



1> Suragch..:

对于Android中准备好的SQLite语句,有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); // 1-based: matches first '?' in sql string
statement.bindString(2, stringValue);  // matches second '?' in sql string

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

查看这些链接,了解有关事务的更多信息以及加​​快数据库插入的速度.

SQLite中的原子提交(深入解释,请参阅第3部分)

数据库事务

Android SQLite批量插入和更新示例

带有INSERT Prepared语句的Android SQLite事务示例

在Android上增加您的SQLite插件

/sf/ask/17360801/

更新行

这是一个基本的例子.您还可以应用上一节中的概念.

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中引入.请参阅此问答.

这是一个例子.

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

通常,当您运行查询时,您希望返回包含大量行的游标.但这不是什么意思SQLiteStatement.除非您只需要一个简单的结果,比如数据库中的行数,您可以使用它来执行查询simpleQueryForLong()

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

通常,您将运行SQLiteDatabase的query()方法来获取游标.

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

有关查询的更多详细信息,请参阅此答案


提醒一下:.bindString/.bindLong/...方法都是从1开始的.

2> jasonhudgins..:

我一直在Android中使用预处理语句,这非常简单:

SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement stmt = db.compileStatement("SELECT * FROM Country WHERE code = ?");
stmt.bindString(1, "US");
stmt.execute();


我不知道这个答案怎么会有这么多的选票.SQLIteStatement #exend不应该用于Sql查询,只能用于语句.请查看http://developer.android.com/reference/android/database/sqlite/SQLiteStatement.html#execute()
**赞成并接受完全不正确的答案的群体心态的完美例子**
请注意,`SQLiteStatement.bindXXX()`具有基于1的索引,而不是基于0的索引.
那么你应该如何使用准备好的语句来查询数据呢?
@jasonhudgins为什么不用INSERT替换SELECT?我刚刚来自[这个](http://stackoverflow.com/questions/23446190/show-the-return-value-of-prepared-statements-in-android#23446190)主题,你在那里混淆了一个初学者
为什么要对select语句使用getWritableDatabase()?不应该是getReadableDatabase()吗?
请编辑您的答案并进行更正.这个答案有误导性.

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> redfish64..:

jasonhudgins的例子不会起作用.您无法执行查询stmt.execute()并获取值(或a Cursor).

您只能预编译根本不返回任何行的语句(例如insert或create table语句)或单个行和列(并使用simpleQueryForLong()simpleQueryForString()).

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有