我正在研究Android,我正在研究使用SQLite数据库。已经知道如何为数据库创建诸如创建查询插入等操作。
例如,假设有以下表定义:
CREATE TABLE bean84_b (id INTEGER PRIMARY KEY AUTOINCREMENT, column_bean BLOB);
然后执行的SQL查询是:
SELECT id, column_bean FROM bean84_b WHERE column_bean=?
执行上述查询的java代码是:
byte[] param1=...
String[] args={String.valueOf(param1)};
Cursor cursor = database(). rawQuery("SELECT id, column_bean FROM bean84_b WHERE column_bean=?", args);
是否可以像SELECT参数一样使用BLOB列?
这是Android数据库API中的设计错误。
query和rawQuery只接受字符串参数。 execSQL接受任何Object参数但不返回结果。 SQLiteStatement接受任何类型的参数,但只允许返回单个值的查询。
另一种类型,你可以将blob与另一个字段http://www.programcreek.com/java-api-examples/index.php?api=android.database.sqlite.SQLiteStatement绑定
在Android数据库API中,execSQL()是参数不是String []而是Object []的唯一函数:
byte[] blob = ...;
db.execSQL("DELETE FROM t WHERE my_blob = ?", new Object[]{ blob });
对的,这是可能的。您必须简单地扩展CursorFactory,将值绑定到将在NewCursor方法中可用的SQLiteQuery。
Xamarin代码片段:
internal sealed class SQLiteCursorFactory : Java.Lang.Object, SQLiteDatabase.ICursorFactory
{
private Dictionary<int, object> _selectionArgs;
internal SQLiteCursorFactory(Dictionary<int, object> selectionArgs)
{
_selectionArgs = selectionArgs;
}
ICursor SQLiteDatabase.ICursorFactory.NewCursor(SQLiteDatabase db, ISQLiteCursorDriver masterQuery, string editTable, SQLiteQuery query)
{
foreach(var key in _selectionArgs.Keys)
{
var val = _selectionArgs[key];
if(val == null)
{
query.BindNull(key);
}
else if(val is int)
{
query.BindLong(key, (int)val);
}
else if (val is long)
{
query.BindLong(key, (long)val);
}
else if (val is double)
{
query.BindDouble(key, (double)val);
}
else if (val is string)
{
query.BindString(key, (string)val);
}
else if (val is byte[])
{
query.BindBlob(key, (byte[]) val);
}
}
return new SQLiteCursor(masterQuery, editTable, query);
}
}
用法:
dbInstance.RawQueryWithFactory(new SQLiteCursorFactory(selectionArgs), query, null, null);