我的程序中有一个模块的奇怪错误,我的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。