2011-03-28 64 views
0

我想将行插入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?

回答

0

你应该打开总是在你需要它的连接。或者在关闭之前先将所有插入物打开。

+0

是的,每次我插入我调用getWritableDatabase()应该“创建和/或打开将用于读取和写入的数据库”。根据文件。这些插入很少被调用,所以我可以打开和关闭每个DB的数据库。看看我的函数prepareDatabase(...)。它在函数的开始处被调用,并将打开一个连接。 – mhradek 2011-03-28 21:24:28

+0

prepareChildDatabase和prepareDatabase是一样的吗? – 2011-03-29 13:20:30

+0

是的,我忘了添加孩子来清理事情。编辑。 – mhradek 2011-03-29 16:28:11

0

首先......当您使用数据库实例或游标实例或Steatment实例(或任何需要在最后关闭的对象)时,请使用以下语法;

SQLiteOpenHelper db; 
    try{ 
     db = myDB.open();//open the database here 
     //do whatever you want with the DB instance 
    }finally{ 
     if(db != null){ 
      db.close(); 
     } 
    } 

如果在进程中间引发异常,您将关闭数据库。

删除这最后

final long id = insertStmt.executeInsert(); 

而要调试好,放了抓在试图/最终,你会看到更好的是怎么回事。

+0

正在离开try/catch/finally最佳实践,直到我更接近实现DataHelper对象。由于这个问题没有抛出它并不能帮助我。我很好奇为什么我应该离开决赛。该建议不符合Java最佳实践。它在executeInsert()的输出中递增得很好。 – mhradek 2011-04-06 19:05:44