我想将行插入Android内的SQLite数据库。将记录插入我的数据库的调用如下所示:DataHelper.insertChild(context,child)。我的目标是将这些功能封装到静态调用的函数中,以处理所有的细节。首先让我与你分享我的代码。Android SQLiteStatement插入;后续调用失败
我通过静态方法这样做:
private static SQLiteDatabase prepareChildDatabase(Context context) {
Log.d(TAG, "DB: prepareChildDatabase");
OpenHelper openHelper = new OpenHelper(context);
return openHelper.getWritableDatabase();
}
然后,我做我的插入:
public static long insertChild(Context context, Child child) {
Log.d(TAG, "DB: insertChild");
SQLiteDatabase db = prepareChildDatabase(context);
SQLiteStatement insertStmt = db.compileStatement(INSERT);
insertStmt.bindLong(1, child.getBirthday().getTime());
// These are optional
if(child.getName() != null) {
insertStmt.bindString(2, child.getName());
} else {
insertStmt.bindNull(2);
}
if(child.getPhoto() != null) {
String photoUri = child.getPhoto().toString();
insertStmt.bindString(3, photoUri);
} else {
insertStmt.bindNull(3);
}
final long id = insertStmt.executeInsert();
// insertStmt.clearBindings(); // Not sure this is necessary
insertStmt.close();
db.close();
return id;
}
对于引用,我OpenHelper是在这里:
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "DB: OpenHelper: onCreate: " + CREATE_CHILDREN_TABLE);
db.execSQL(CREATE_CHILDREN_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
最后,变量,陈述和表格:
private static final String TABLE_NAME = "children";
private static final String COL_NAME = "name";
private static final String COL_BDAY = "birthday";
private static final String COL_PHOTO = "photo";
private static final String INSERT = "insert into "
+ TABLE_NAME + " ("
+ COL_BDAY + ", "
+ COL_NAME + ", "
+ COL_PHOTO + ") values (?, ?, ?)";
private static final String UPDATE = "update "
+ TABLE_NAME + "set "
+ COL_BDAY + " = ?, "
+ COL_NAME + " = ?, "
+ COL_PHOTO + " = ?) WHERE "
+ BaseColumns._ID + " = ?";
private static final String CREATE_CHILDREN_TABLE =
"CREATE TABLE " + TABLE_NAME + " ("
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COL_BDAY + " INTEGER NOT NULL, "
+ COL_NAME + " TEXT NULL, "
+ COL_PHOTO + " TEXT NULL)";
所以发生的事情是,我第一次称此为一切正常。插入工作,数据在那里,我可以将数据库从设备导出到我的SQLite浏览器。随后调用insertChild(...)会中断数据库。打开不起作用,SQLiteBrowser不显示任何表或行,并在文本编辑器中打开它显示一些内容;我的猜测是数据库已损坏。没有更多行正在插入,我无法读取它。 没有任何错误抛出。
我猜这是两件事情之一。首先,我的手柄没有正确打开/关闭,某些参考文件正在被随后的调用取代。其次,我对准备好的陈述的理解是错误的。事情是,我看看代码,它似乎很好。打开数据库,绑定到准备好的语句,执行,关闭语句,关闭数据库。
有人愿意帮我解决这个问题吗?我一直在记录日志,寻找异常,尝试东西,但似乎没有任何工作。我想我可能只是错过了一些细节。这或我疯了。
感谢,
迈克
更新
我已经把我的注意力转向线程,因为这个问题并不在我的模拟器重现。看看这些链接:
http://www.kagii.com/journal/2010/9/10/android-sqlite-locking.html
android sqlite application is being forcefully closed on device
What are the best practices for SQLite on Android?
是的,每次我插入我调用getWritableDatabase()应该“创建和/或打开将用于读取和写入的数据库”。根据文件。这些插入很少被调用,所以我可以打开和关闭每个DB的数据库。看看我的函数prepareDatabase(...)。它在函数的开始处被调用,并将打开一个连接。 – mhradek 2011-03-28 21:24:28
prepareChildDatabase和prepareDatabase是一样的吗? – 2011-03-29 13:20:30
是的,我忘了添加孩子来清理事情。编辑。 – mhradek 2011-03-29 16:28:11