Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 将sqlite查询作为游标或对象/列表返回_Android_Sqlite - Fatal编程技术网

Android 将sqlite查询作为游标或对象/列表返回

Android 将sqlite查询作为游标或对象/列表返回,android,sqlite,Android,Sqlite,几年前,当我启动应用程序时,我做了一些教程,并且总是对返回光标的数据库进行查询(不关闭光标): 现在我正在将代码重构为MVVM并添加模型,因此我将代码更改为: public Card querySingleId(String szId) { SQLiteDatabase db = getWritableDatabase(); Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, _ID + " = ?", new String[]{

几年前,当我启动应用程序时,我做了一些教程,并且总是对返回光标的数据库进行查询(不关闭光标):

现在我正在将代码重构为MVVM并添加模型,因此我将代码更改为:

public Card querySingleId(String szId) {
    SQLiteDatabase db = getWritableDatabase();
    Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, _ID + " = ?", new String[]{szId}, null, null, null);
    c1.moveToFirst();

    return new Card(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
                    c1.getString(c1.getColumnIndex(DbHandler.STREET)),
                    c1.getString(c1.getColumnIndex(DbHandler.CITY)));
}
我读到游标应该总是关闭的(内存泄漏)。从数据库返回数据的最佳/最符合的方法是什么?我也不确定是否有多个结果,我应该使用光标还是更改为列表

public List<Card> queryAll() {
    SQLiteDatabase db = getWritableDatabase();
    Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, null, null, null, null, null);
    List<Card> list = new ArrayList<>();

    if(c1.moveToFirst()){
        do{
            list.add(new Card(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
                              c1.getString(c1.getColumnIndex(DbHandler.STREET)),
                              c1.getString(c1.getColumnIndex(DbHandler.CITY))));
        } while(c1.moveToNext());
    }
    c1.close();
    return list;
}
public List queryAll(){
SQLiteDatabase db=getWritableDatabase();
游标c1=db.query(表_ADR,szGetTableEntries,null,null,null,null);
列表=新的ArrayList();
if(c1.moveToFirst()){
做{
添加(新卡(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
c1.getString(c1.getColumnIndex(DbHandler.STREET)),
c1.getString(c1.getColumnIndex(DbHandler.CITY));
}而(c1.moveToNext());
}
c1.关闭();
退货清单;
}
这仅仅是一个品味问题,还是有理由返回游标或列表/对象?根据代码中需要数据的位置,列表或光标更方便。
我只是不确定在sqlite查询中什么是正确的方法。代码示例太多了,但似乎大多数都是复制/粘贴,没有真正深入主题。

如果查询可以返回多行,那么您应该返回一个列表

如果您确定查询将只返回一张卡,那么返回这张卡就可以了(可能更可取)但是您应该关闭光标

  • 但是,没有实际的要求/需要这样做(例如,如果您的初始活动将光标用于ListView/Spinner,则您可能不想关闭光标,而是重新使用光标,并在活动恢复时使用适配器的swapCursor)。光标将被有效地关闭,当应用程序完成时,数据库也将被关闭

  • 由于您使用了列_ID,该列通常用于作为rowid列别名的列,该列通常由SQLite生成,因此,如果使用/定义为该列(列已显式或隐式定义为整数主键,带或不带AUTOINCREMENT)然后它将是一个唯一的值,并且只返回一行,因为您有_ID=?。因此,很可能只返回一行或不返回任何行,并且不太可能返回多行

因此(对于单张卡):-

应该是这样的:-

public Card querySingleId(String szId) {
    SQLiteDatabase db = getWritableDatabase();
    Card rv = null;
    Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, _ID + " = ?", new String[]{szId}, null, null, null);
    if (c1.moveToFirst()) { //<<<<<< Should always check if the move moved 
        rv = new Card(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
            c1.getString(c1.getColumnIndex(DbHandler.STREET)),
            c1.getString(c1.getColumnIndex(DbHandler.CITY)));
    }
    c1.close();
    return rv; //<<<<< Note should check the returned Card for null
}
public Card querySingleId(字符串szId){
SQLiteDatabase db=getWritableDatabase();
卡rv=空;
游标c1=db.query(表_ADR,szGetTableEntries,_ID+“=?”,新字符串[]{szId},null,null,null);

if(c1.moveToFirst()){//如果您正在重构和改进代码,为什么不直接移动到每个游标,在使用它之后必须关闭它,不再需要它。如果您的方法返回一个游标,您可以在返回它的位置使用它之后关闭它。仅当您确实需要它时才使用列表。我希望将来移动到房间,但目前我不能,因为我需要在运行时和afaik期间创建新表这在room@bytesculptor从技术上讲,您可以在运行时在room中创建表,但在一段时间内,您无法也可能无法做到的是创建关联的类(实体)在运行时构建,您将失去room方法提供的一些优势。您仍然可以使用它们,这可能会有点尴尬。
public Card querySingleId(String szId) {
    SQLiteDatabase db = getWritableDatabase();
    Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, _ID + " = ?", new String[]{szId}, null, null, null);
    c1.moveToFirst();

    return new Card(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
                    c1.getString(c1.getColumnIndex(DbHandler.STREET)),
                    c1.getString(c1.getColumnIndex(DbHandler.CITY)));
}
public Card querySingleId(String szId) {
    SQLiteDatabase db = getWritableDatabase();
    Card rv = null;
    Cursor c1 = db.query(TABLE_ADR, szGetTableEntries, _ID + " = ?", new String[]{szId}, null, null, null);
    if (c1.moveToFirst()) { //<<<<<< Should always check if the move moved 
        rv = new Card(c1.getString(c1.getColumnIndex(DbHandler.NAME)),
            c1.getString(c1.getColumnIndex(DbHandler.STREET)),
            c1.getString(c1.getColumnIndex(DbHandler.CITY)));
    }
    c1.close();
    return rv; //<<<<< Note should check the returned Card for null
}