java - Sqlite 插入无法正常工作

标签 java android sqlite

第一次在这里编写Android应用程序。

我的用例如下:在一个 Activity 中,我有一个显示摘要(金额总和)的TextView,以及一个带有EditTextButton。这个想法是按下按钮添加一个条目到 sqlite 数据库。

问题是,每次我按下按钮时,似乎输入中的先前值都被添加到数据库中。

  1. 输入10 -> 按下按钮 -> 无 react
  2. 输入 7 -> 按下按钮 -> 摘要更改 10
  3. 输入 3 -> 按下按钮 -> 摘要更改 7 等等

这是 OnClickListener 中使用的方法:

public static void addExpense(Context ctx, Expense expense) {
        ExpensesDbHelper dbHelper = new ExpensesDbHelper(ctx);
        SQLiteDatabase db = dbHelper.getWritableDatabase();


        ContentValues values = expense.toContentValues();
        Log.i("Daily-", "addExpense: " + values.toString());

        long newRowId;
        db.beginTransaction();
        try {
            newRowId = db.insert(
                    ExpensesReaderContract.ExpenseEntry.TABLE_NAME,
                    null,
                    values);

            db.setTransactionSuccessful();
        } finally{
            db.endTransaction();
        }


        Log.i("Daily-", "addExpense: new id " + newRowId);
        Cursor c = db.rawQuery("SELECT COUNT(*) from entry", null);
        c.moveToFirst();
        Log.i("Daily-", "Number of rows: " + c.getInt(0));
        c.close();

        Log.i("Daily-", "addExpense: Existing " + Expense.printable(getExpenses(db)));
    }

这是来自该输入序列的日志语句:

I/Daily-: addExpense: timestamp=2015-11-07 16:44:38 comment=Expense amount=10.0
I/Daily-: addExpense: new id 1
I/Daily-: Number of rows: 1
I/Daily-: addExpense: Existing 
I/Daely-Log: 9
I/Daily-: addExpense: timestamp=2015-11-07 16:44:41 comment=Expense amount=7.0
I/Daily-: addExpense: new id 2
I/Daily-: Number of rows: 2
I/Daily-: addExpense: Existing Expense(10.000000,Expense,2015-11-07T16:44:38.000Z), 
I/Daely-Log: 9
I/Daily-: addExpense: timestamp=2015-11-07 16:44:44 comment=Expense amount=3.0
I/Daily-: addExpense: new id 3
I/Daily-: Number of rows: 3
I/Daily-: addExpense: Existing Expense(7.000000,Expense,2015-11-07T16:44:41.000Z), Expense(10.000000,Expense,2015-11-07T16:44:38.000Z), 

下面是处理事件流的 Activity 的代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_summary);
        showAvailable();

        Button addExpenseButton = (Button) findViewById(R.id.add_expense);
        final EditText amountField = (EditText) findViewById(R.id.amount);

        addExpenseButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                try {
                    float amount = Float.parseFloat(amountField.getText().toString());
                    addExpense(amount, "Expense");

                    showAvailable();
                } catch (NumberFormatException e) {

                }
            }

        });
    }

现在很明显,在db.insert返回后,该行仍然不在它应该在的位置。

如何保证下次调用 getExpenses 一定会返回新行?

感谢您的帮助。

更新:Expense是一个非常简单的类:

public class Expense {
    public static DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private float amount;

    public float getAmount() {
        return amount;
    }

    public String getComment() {
        return comment;
    }

    public DateTime getTimestamp() {
        return timestamp;
    }

    private String comment;
    private DateTime timestamp;

    public Expense(float amount, String comment, DateTime timestamp) {
        this.amount = amount;
        this.comment = comment;
        this.timestamp = timestamp;
    }
    ...
     public ContentValues toContentValues() {
        ContentValues values = new ContentValues();
        values.put(ExpensesReaderContract.ExpenseEntry.COLUMN_NAME_AMOUNT, getAmount());
        values.put(ExpensesReaderContract.ExpenseEntry.COLUMN_NAME_COMMENT, getComment());
        values.put(ExpensesReaderContract.ExpenseEntry.COLUMN_NAME_TIMESTAMP, iso8601Format.format(getTimestamp().toDate()));
        return values;
    }
}

最佳答案

您的日志表明插入确实有效 - 您得到了正确的COUNT(*),不是吗?我更关心 Expense.printable()getExpenses() 中的问题,但您在发布代码时似乎已经剪掉了这部分代码。最有可能的是,您在附近的某个地方丢失了一行。

如果我猜的话,您正在 getExpenses() 方法中执行类似的操作:

if (cursor.moveToFirst()) {
    while(cursor.moveToNext()) {
        <stuff>
    }
}

这会让你错过第一行。如果这证明是您的问题,只需跳过 moveToFirst() 调用,或将循环更改为 do-while。

关于java - Sqlite 插入无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33585248/

相关文章:

java - 为什么我在使用 --option 运行时进行协同设计后无法启动 Java 应用程序

android - 如何设置BottomBar的背景颜色?

android - 使用 Android SDK 检测附近移动设备的方法?

java - 将字符串(最多 10 个字符)打印为菱形

java - Parcelable 对象错误 : Unmarshalling unknown type code *** at offset ***

java - HBase多线程扫描真的很慢

java - 解决许多proguard警告

c# - 通过 NHibernate 在不加载对象的情况下更新一对多关系

vb.net - SQLite 数据库文件放在网络文件夹中时无法打开

c# - 附加限制 > 10