Android开发中SQLite中主键的行为

时间:2014-07-24 02:45:12

标签: android sql sqlite

我的SQLite数据库游标有一个ArrayAdapter来填充Spinner,如下所示:

public void loadSpinnerData() {
    List<String> names = db.getAllWalletName();

    ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(
            getActivity().getApplicationContext(), R.layout.spinner_item,
            names);

    dataAdapter.setDropDownViewResource(R.layout.spinner_item);
    spinner.setAdapter(dataAdapter);

}

public void onItemSelected(AdapterView<?> parent, View view, int position,
        long id) {
    current_wallet_id = position + times; // times = 1
    double sum = db.getSum(current_wallet_id);
    wallet_sum.setText(String.valueOf(sum));

这是数据库。

    public void onCreate(SQLiteDatabase db) {
    String CREATE_WALLET_TABLE = "CREATE TABLE " + TABLE_WALLET + " ( "
            + KEY_WALLET_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + KEY_WALLET_NAME + " TEXT UNIQUE NOT NULL , " + KEY_WALLET_SUM
            + " REAL NOT NULL )";

    db.execSQL(CREATE_WALLET_TABLE);

    String CREATE_TRANSACTION_TABLE = "CREATE TABLE " + TABLE_TRANSACTION
            + " ( " + KEY_TRANS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + KEY_AMOUNT + " REAL NOT NULL, " + KEY_WALLET_ID
            + " INTEGER NOT NULL, " + KEY_DESCRIPTION + " TEXT)";

    db.execSQL(CREATE_TRANSACTION_TABLE);

}

    public List<String> getAllWalletName() {
    List<String> names = new ArrayList<String>();
    SQLiteDatabase db = this.getReadableDatabase();

    String selectQuery = "Select " + KEY_WALLET_NAME + " FROM "
            + TABLE_WALLET;
    Cursor c = db.rawQuery(selectQuery, null);

    if (c.moveToFirst()) {
        do {
            names.add(c.getString(0));
        } while (c.moveToNext());
    }

    c.close();
    db.close();
    return names;
}

    public double getSum(int id) {
    SQLiteDatabase db = this.getReadableDatabase();

    String selectQuery = "SELECT * FROM " + TABLE_WALLET + " WHERE "
            + KEY_WALLET_ID + " = " + id;

    Cursor c = db.rawQuery(selectQuery, null);

    if (c.moveToFirst()) {
        return c.getDouble(c.getColumnIndex(KEY_WALLET_SUM));
    } else
        return 0;
}

我对这个Spinner也有一个onItemSelected。我尝试将微调器int position插入db.getSum的参数中。一切正常,但我害怕我曾经在Microsoft Access中看到的SQL行为,即删除记录时,主键值也被删除,并且没有记录将被填充。

ID      Name
1       Dean
2       Sophie
3       Lachland
4       Pete

因此,基于前面的陈述,如果我删除第一个并添加另一个记录,它将看起来像

ID      Name
1       Dean
2       Sophie
3       Lachland
5       Roland

那么如果ID不像Spinner上显示的那样精确,我如何填写'getSum'参数?或者这只是Microsoft Access的行为之一?你能为此建议任何解决方法吗?我确实认为这是一个非常普遍的问题,但是我在半小时的谷歌搜索后找不到答案。

2 个答案:

答案 0 :(得分:1)

问题是你的方法不正确。您的id参数取决于微调器的位置,而不应该:

current_wallet_id = position + times; // times = 1

因此,当主要ID没有订单时,您的ID是错误的 的解决方案: 尝试创建一个至少包含两个字段的自定义适配器:id&amp;包含在对象中的名称。您可以参考this 它看起来像这样:

  private class Wallet{
     int id;
     int name;
  }

你得到所有的钱包方法:

public List<Wallet> getAllWalletName() {
    // select id and name, then pass to Wallet object
}

最后,在适配器中:

 // do your own to create custom adapter
 CustomAdapter adapter = new CustomAdapter();

public void onItemSelected(AdapterView<?> parent, View view, int position,
    long id) {
    Wallet item  = adapter .get(position);
    double sum = db.getSum(item.id );
    wallet_sum.setText(String.valueOf(sum));
}

希望这可以提供帮助

答案 1 :(得分:0)

您需要使用数组ID:

来确定Spinner的位置

变化:

public List<String> getAllWalletName() {
List<String> names = new ArrayList<String>();
SQLiteDatabase db = this.getReadableDatabase();

String selectQuery = "Select " + KEY_WALLET_NAME + " FROM "
        + TABLE_WALLET;
Cursor c = db.rawQuery(selectQuery, null);

if (c.moveToFirst()) {
    do {
        names.add(c.getString(0));


    } while (c.moveToNext());
}

TO:

public List<mObjectNames> getAllWalletName() {
List<mObjectNames> names = new ArrayList<mObjectNames>();



SQLiteDatabase db = this.getReadableDatabase();

String selectQuery = "Select * FROM "+ TABLE_WALLET;
Cursor c = db.rawQuery(selectQuery, null);

if (c.moveToFirst()) {
    do {
mObjectNames mUnicobjectName = cursorToobjectName(c);
names.add(mUnicobjectName);

    } while (c.moveToNext());
}

private mObjectNames cursorToobjectName(Cursor cursor){
mObjectNames objectName = new mObjectNames();

objectName.setKEY_WALLET_ID(c.getLong(0));
objectName.setKEY_WALLET_NAME(c.getString(1));


return objectName;
}

类mObjectNames:

public class mObjectNames {

long KEY_WALLET_ID;
String KEY_WALLET_NAME; 
String KEY_WALLET_SUM; // i am not sure if  REAL NOT NULL , is an String, integer...

private void setKEY_WALLET_ID(long KEY_WALLET_ID){
this.KEY_WALLET_ID = KEY_WALLET_ID;
}

private long getKEY_WALLET_ID(){
return KEY_WALLET_NAME;
}

private void setKEY_WALLET_NAME(String KEY_WALLET_NAME){
this.KEY_WALLET_NAME = KEY_WALLET_NAME;
}

private String getKEY_WALLET_NAME(){
return KEY_WALLET_ID;
}


}

列出所有人:

List<mObjectNames> names = db.getAllWalletName();

// Convert Object to Array for show in ArrayAdapter needs the conversion.

String arrayOfValues [] = new String[names.size()]; 

for (int i = 0; i < names.size(); i++) {
arrayOfValues[i] = names.get(i).getKEY_WALLET_NAME;

}   

并且:

public void onItemSelected(AdapterView<?> parent, View view, int position,long id) {

// int position, matches with the position in the List 'names'
String id = names.get(position).getKEY_WALLET_NAME;
long id= names. get(position).getKEY_WALLET_ID
// With that, dont care the Id, or The position.

}