【发布时间】:2015-10-14 22:05:28
【问题描述】:
我在 DatabaseHelper 类中创建了一个简单的 SQLite 数据库,该类扩展了 SQLiteOpenHelper。该数据库包含两列,NAME 和DESCRIPTION。这是在 DatabaseHelper 类中的 onCreate 方法中运行的方法
@Override
public void onCreate(SQLiteDatabase db) {
updateMyDatabase(db, 0, DATABASE_VERSION);
}
private void updateMyDatabase(SQLiteDatabase db, int olderVersion, int newerVersion){
if (olderVersion<1){
db.execSQL("CREATE TABLE MARK (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "NAME TEXT, "
+ "DESCRIPTION TEXT);");
insertDrink(db,"latte","Espresso and Steamed Milk");
insertDrink(db, "cappuccino", "This a Cappuccino");
}
}
private static void insertDrink(SQLiteDatabase database, String name, String description){
ContentValues drinkValues = new ContentValues();
drinkValues.put("NAME", name);
drinkValues.put("DESCRIPTION",description);
database.insert("MARK",null,drinkValues);
}
我的具体问题是关于创建数据库时使用的 _id INTEGER PRIMARY KEY。这个数字是从 1 还是 0 开始的?
这就是我想知道的原因。我有一个包含两个项目的简单 ListView。我单击第一项并将 ListView 的位置(即 0)传递给不同的活动。
listView.setOnItemClickListener(new ListView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch(position){
case 0:{
Intent i = new Intent(MainActivity.this, Details.class);
i.putExtra(Details.EXTRA_DRINKNUM,(int)id);
startActivity(i);
break;
}
case 1:{
Intent i = new Intent(MainActivity.this, Details.class);
i.putExtra(Details.EXTRA_DRINKNUM,(int)id);
startActivity(i);
break;
}
}
}
});
然后我在那个 Activity 中检索这个数字,并将它放在一个名为 clickNum 的变量中。
然后我使用 clickNum 查询数据库:
SQLiteOpenHelper database = new DatabaseHelper(this);
SQLiteDatabase db = database.getReadableDatabase();
Cursor cursor = db.query("MARK",
new String[]{"NAME","DESCRIPTION"},
"_id = ?",
new String[]{Integer.toString(clickNum)},
null,null,null);
如果我做drinkNum + 1,我只能拉出包含数据的第一行(Latte ....)。这是为什么呢?第一行_id不应该是0???
这里更详细的看一下查询数据库的类(Details):
public class Details extends AppCompatActivity {
private TextView name, description;
public static final String EXTRA_DRINKNUM = "DrinkNum";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
name = (TextView)findViewById(R.id.detailsCoffeeName);
description = (TextView)findViewById(R.id.detailsCoffeeDescription);
int clickNum = (Integer)getIntent().getExtras().get(EXTRA_DRINKNUM);
ContentValues values = new ContentValues();
values.put("DESCRIPTION", "Lateeeee");
try{
SQLiteOpenHelper database = new DatabaseHelper(this);
SQLiteDatabase db = database.getReadableDatabase();
Cursor cursor = db.query("MARK",
new String[]{"NAME","DESCRIPTION"},
"_id = ?",
new String[]{Integer.toString(clickNum)},
null,null,null);
if (cursor.moveToFirst()){
String nameText = cursor.getString(0);
String descriptionText = cursor.getString(1);
name.setText(nameText);
description.setText(descriptionText);
}else{
Log.v("Details", "Nothing Found");
}
cursor.close();
db.close();
}catch(SQLiteException e){
e.printStackTrace();
Toast.makeText(this, "Database Issue", Toast.LENGTH_LONG).show();
}
【问题讨论】:
-
您的应用程序中有一个错误:您假设
ListViewposition与_ID值有任何关系。由于数据库操作(例如,删除一行)或应用程序操作(例如,对结果进行排序),这些通常不会匹配。请使用_ID值本身。例如,传递给您的项目点击侦听器的long id是_ID,而CursorAdapter上的getItemId()将为您提供给定_ID的_ID。 -
对不起,我不是更清楚,是的,在我的 itemClickListener 中,我将一个长 id 传递给下一个活动。我在一个名为 clickNum 的变量中检索它,然后使用它来查询数据库。我的问题是我传递的长 id,例如第一项的 0 不会显示我的数据库的第一行。如果我将 1 添加到我传递的长 id (clickNum + 1),它只会显示第一行。是因为数据库的 AutoIncrement 是从 1 而不是 0 开始的吗?
-
"是因为数据库的自动增量从 1 开始,而不是 0?" - 不。
clickNum在你的Integer.toString(clickNum)中来自哪里?你确定是来自Details.EXTRA_DRINKNUM? -
我添加了更多包含查询的类。 clickNum 来自这行代码:int clickNum = (Integer)getIntent().getExtras().get(EXTRA_DRINKNUM);
-
你在使用
CursorAdapter吗?或者,当您查询数据库时,您是否将数据倒入与另一种适配器(例如,ArrayAdapter)一起使用的其他东西(例如 POJO 数组)中?