Android SQLite在使用SqliteDatabase.query()

时间:2016-09-30 06:24:15

标签: android sqlite

我的程序中有一个模块的奇怪错误,我的Sqlite数据库表中的数据的整数主键在从数据库通过.query()读取时会增加。我还将我的SqliteDatabase作为DatabaseOpenHelper.getReadableDatabase()启动,并且我希望我的主键只会在插入期间递增(.insert())。

UI与RecyclerView列表一样基本,让我们调用此ListA,在单击某个项目时,它将显示一个自定义对话框,其中包含允许多个选择的另一个列表,通过复选框,以及一个额外的复选框,其中包含一个接受String的附加EditText;让我们称之为ListB。这个包含ListB的自定义对话框有两个按钮,一个是取消,另一个是保存和"记忆"用户选择的项目,因为在通过取消关闭自定义对话框后,仍然可以再次访问此ListB。

基本上我有两个由点击触发的方法(有一些单独的方法来隔离功能)。请原谅我的方法名称,因为我已经做了一些解决方案来解决这个问题。

单击ListA中的项目时会触发以下方法。

private void createRemarksObjects2(JSONArray remarks) {
    if (lstRemarks != null) {
        lstRemarks.clear();

        String remarksKey = "remark";
        DataManager    dm = DataManager.getInstance(mContext);
        SQLiteDatabase db = dm.getReadableDatabase();

        logTableValues(db.query(Schema.TableFindingRemarks.NAME, null, null, null, null, null, null));

        // loop on the JSONArray
        for (int i = 0; i < remarks.length(); i++) {
            try {
                JSONObject remark = remarks.getJSONObject(i);

                if (remark.getString(remarksKey).equals(ComponentRemark.OTHERS_KEY)) {
                    String[] columns   = { Schema.TableFindingRemarks.NOTE };
                    String whereClause = String.format("%s = ? AND %s = ?", Schema.TableFindingRemarks.FINDING_ID, Schema.TableFindingRemarks.REMARK_NAME);
                    String[] whereArgs = {String.valueOf(mComponentId), remark.getString(remarksKey)};

                    Cursor cursor2 = db.query(Schema.TableFindingRemarks.NAME, columns, whereClause, whereArgs, null, null, null);
                    cursor2.moveToFirst();

                    ComponentRemark otherRemark;
                    if (cursor2.getCount() > 0) {
                        otherRemark = new ComponentRemark(i, ComponentRemark.OTHERS_REMARK, ComponentRemark.OTHERS_KEY, cursor2.getString(cursor2.getColumnIndex(Schema.TableFindingRemarks.NOTE)), cursor2.getCount() > 0);
                    } else {
                        otherRemark = new ComponentRemark(i, ComponentRemark.OTHERS_REMARK, ComponentRemark.OTHERS_KEY, "", false);
                    }

                    lstRemarks.add(otherRemark);
                    cursor2.close();
                } else {
                    String[] columns   = { Schema.TableFindingRemarks.ID };
                    String whereClause = String.format("%s = ? AND %s = ?", Schema.TableFindingRemarks.FINDING_ID, Schema.TableFindingRemarks.REMARK_NAME);
                    String[] whereArgs = {String.valueOf(mComponentId), remark.getString(remarksKey)};

                    Cursor cursor1 = db.query(Schema.TableFindingRemarks.NAME, columns, whereClause, whereArgs, null, null, null);
                    cursor1.moveToFirst();

                    ComponentRemark componentRemark = new ComponentRemark(i, remark.getString(remarksKey), cursor1.getCount() > 0);

                    lstRemarks.add(componentRemark);
                    cursor1.close();
                }

            } catch (JSONException e) {
                e.printStackTrace();
                Toast.makeText(mContext, "JSON exception error! Please contact the administrator", Toast.LENGTH_SHORT).show();
            }
        }

        db.close();
    } else {
        lstRemarks = new ArrayList<>();
    }
}

此方法接受包含要呈现的项目的JSONArray,并检查数据库是否该特定项目当前是否保存在sqlite数据库表中,如果是,则该项目将在选中时标记。

当用户单击自定义对话框中的“保存/更新”按钮时,将触发下一个方法。

 private void updateSelectedRemarks2() {
    DataManager    dm = DataManager.getInstance(mContext);
    SQLiteDatabase db = dm.getWritableDatabase();
    List<ContentValues> lstRows = getCheckedRemarks(db);

    if (lstRows == null) {
        Toast.makeText(mContext, "Please input notes for 'others' remark", Toast.LENGTH_SHORT).show();
    } else {
        if (lstRows.size() > 0) {
            for (ContentValues values : lstRows) {
                String whereClause = String.format("%s = ? AND %s = ?", Schema.TableFindingRemarks.FINDING_ID, Schema.TableFindingRemarks.REMARK_NAME);
                String[] whereArgs = { String.valueOf(mComponentId), values.getAsString(Schema.TableFindingRemarks.REMARK_NAME) };
                String[] columns = { String.valueOf(Schema.TableFindingRemarks.ID) };
                Cursor cursor = db.query(Schema.TableFindingRemarks.NAME, columns, whereClause, whereArgs, null, null, null, null);

                if (cursor.getCount() > 0) {
                    cursor.moveToFirst();
                    String updateWhere = String.format("%s = ?", Schema.TableFindingRemarks.ID);
                    String[] updateWhereArgs = { String.valueOf(cursor.getInt(cursor.getColumnIndex(Schema.TableFindingRemarks.ID))) };
                    db.update(Schema.TableFindingRemarks.NAME, values, updateWhere, updateWhereArgs);
                } else {
                    db.insert(Schema.TableFindingRemarks.NAME, null, values);
                }

                cursor.close();
                broadcastToListeners();
                dismiss();
            }
        }
    }

    logTableValues(db.query(Schema.TableFindingRemarks.NAME, null, null, null, null, null, null));
    db.close();
}

private List<ContentValues> getCheckedRemarks(SQLiteDatabase db) {
    List<ContentValues> lstRows = new ArrayList<>();

    for (ComponentRemark remark : lstRemarks) {
        ContentValues values = new ContentValues();
        values.clear();

        if (remark.isChecked()) {
            if (remark.getRemarkType() == ComponentRemark.NORMAL_REMARK) {
                values.put(Schema.TableFindingRemarks.FINDING_ID,  mComponentId);
                values.put(Schema.TableFindingRemarks.REMARK_NAME, remark.getLabel());
            } else {
                if (remark.getRemarkType() == ComponentRemark.OTHERS_REMARK) {
                    if (remark.getNote().equals("") || remark.getNote() == null) {
                        return null;
                    } else {
                        values.put(Schema.TableFindingRemarks.FINDING_ID,  mComponentId);
                        values.put(Schema.TableFindingRemarks.REMARK_NAME, remark.getLabel());
                        values.put(Schema.TableFindingRemarks.NOTE, remark.getNote());
                    }
                } else {
                    Toast.makeText(mContext, "There's something wrong with the data. Please contact the administrator", Toast.LENGTH_SHORT).show();
                }
            }

            lstRows.add(values);
        }

    }

    return lstRows;
}

第一种方法是触发的方法,还处理ListB中已检查/选定项目的最终保存/更新。当项目已存在于数据库中时,该方法将更新项目而不是插入另一项目。第二种方法getCheckedRemarks()(忽略参数),检查是否通过与数据库中的数据行对应的模型类检查了项,并且正在更新返回布尔值的ComponentRemark.isChecked()方法通过检查/取消选中ListB中的项目(工作正常BTW)。

ListB上的最后一项始终标记为&#34;其他&#34;,并从其旁边的EditText接受一个String。当此String为空时,getCheckedRemarks()将返回null,而不是在第一个方法updateSelectedRemarks2()中作为我的验证检查。

现在,问题是,当我单击ListA中的某个项目,并且此ListA的ListB之前已经选择了项目时,将检查项目,但是#Te;其他&#34的EditText上的字符串; item不会出现,不是因为UI错误,而是因为它在数据库中变为NULL。

保存ListB的选定项目后,数据库中的项目完好无损,但是当我重新单击ListA中的特定项目时,数据的ID都会增加1,&#34;注意&#34; &#34;其他&#34; item变为NULL。

我还制作了一个显示表中所有数据行的方法,名为logTableValues()。

private void logTableValues(Cursor cursor) {
    String TAG = "note-track";
    String headers = "";
    String rows = "";

    if (cursor.getCount() > 0) {
        for (String colname : cursor.getColumnNames()) {
            headers += "| " + colname;
        }

        while (cursor.moveToNext()) {
            for (int i = 0; i < cursor.getColumnCount(); i++) {
                rows += "| " + cursor.getColumnName(i) + "=" + cursor.getString(i);
            }
            rows += "\n";
        }
    } else {
        Log.i(TAG, "nothing can be seen");
    }

    String log = "Table Schema:\n" + headers + "\n" + rows;
    Log.i(TAG, log);
    cursor.close();
}

此日志是在保存我的选择之后:

    09-30 14:18:51.685 578-578/com.victoriacourt.autopilot I/note-track: Table Schema:
                                                                     | id| finding_id| name| note
                                                                     | id=130| finding_id=1| name=PAINT FADED| note=
                                                                     | id=131| finding_id=1| name=BUSTED LIGHT| note=
                                                                     | id=132| finding_id=1| name=OTHERS| note=sample

这些是我从ListA重新打开自定义对话框时出现的日志

    09-30 14:20:36.566 578-578/com.victoriacourt.autopilot I/note-track: Table Schema:
                                                                     | id| finding_id| name| note
                                                                     | id=133| finding_id=1| name=PAINT FADED| note=
                                                                     | id=134| finding_id=1| name=BUSTED LIGHT| note=
                                                                     | id=135| finding_id=1| name=OTHERS| note=
09-30 14:20:37.706 578-578/com.victoriacourt.autopilot I/note-track: Table Schema:
                                                                     | id| finding_id| name| note
                                                                     | id=133| finding_id=1| name=PAINT FADED| note=
                                                                     | id=134| finding_id=1| name=BUSTED LIGHT| note=
                                                                     | id=135| finding_id=1| name=OTHERS| note=
09-30 14:20:42.686 578-578/com.victoriacourt.autopilot I/note-track: Table Schema:
                                                                     | id| finding_id| name| note
                                                                     | id=136| finding_id=1| name=PAINT FADED| note=
                                                                     | id=137| finding_id=1| name=BUSTED LIGHT| note=
                                                                     | id=138| finding_id=1| name=OTHERS| note=

我在这个GitHub项目中使用这个库/文件: https://github.com/sanathp/DatabaseManager_For_Android 当我通过这些代码创建的活动按数据库查看时,ID也会再次递增,但多次不再增加ID。

0 个答案:

没有答案