Android数据库使用货币/余额

时间:2013-07-07 15:08:36

标签: java android database sqlite

我正在开发一个管理用户费用和收入的应用程序,我已经达到了一个我非常困难的地步,我觉得我需要一些帮助,我想要做的就是保存记录总用户余额和根据用户的行为,能够对其进行计算,如果他的余额为100美元而且他增加了50美元的费用,则节省的余额将更新为总计50美元等。

我不确定这样做的正确方法是什么,或者如何编写数据库函数来对“balance”变量进行数学运算,这是我的数据库类到目前为止,我真的很感激任何示例或提示。

现在我所拥有的只是基本的“添加,更新,删除,获取”功能......

public class TransactionsDatabase {

private static final String DATABASE_NAME = "transactions_db";
private static final String DATABASE_TABLE = "transactions_table";
private static final int DATABASE_VERSION = 1;

private static final String TRANSACTION_ID = "_id";
private static final String TRANSACTION_AMOUNT = "amount";
private static final String TRANSACTION_DESCRIPTION = "description";
private static final String TRANSACTION_DATE = "date";
private static final String TRANSACTION_CATEGORY = "category";
private static final String TRANSACTION_CURRENCY = "currency_type";
private static final String TRANSACTION_EXPENSE_OR_INCOME = "expenseOrIncome";
private static int BALANCE; // this is how I have tried to use the balance so far...

private static final String CREATE_DATABASE = "create table transactions_table (_id integer primary key autoincrement, "
+ "amount integer not null, date text not null, category text not null, currency_type text not null, description text not null, expenseOrIncome text not null);";

private static final String TAG = "TransactionsDatabase";
private DatabaseHelper DbHelper;
private SQLiteDatabase SqlDatabase;
private final Context ctx;

private static class DatabaseHelper extends SQLiteOpenHelper {

    public DatabaseHelper(Context context) {

        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL(CREATE_DATABASE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will erase old data");
        db.execSQL("DROP TABLE IF EXISTS expenses_table");
        onCreate(db);
    }       
}

TransactionsDatabase (Context c) {
    this.ctx = c;
}

public TransactionsDatabase open() throws SQLException {

    DbHelper = new DatabaseHelper(ctx);
    SqlDatabase = DbHelper.getWritableDatabase();
    return this;

}

public void close() {

    DbHelper.close();
}

public long createExpenseOrIncome (int amount, String description, String date, String category, String currency_type, String expenseOrIncome) {

    ContentValues values = new ContentValues();
    values.put(TRANSACTION_AMOUNT, amount);
    values.put(TRANSACTION_DESCRIPTION, description);
    values.put(TRANSACTION_DATE, date);
    values.put(TRANSACTION_CATEGORY, category);
    values.put(TRANSACTION_CURRENCY, currency_type);
    values.put(TRANSACTION_EXPENSE_OR_INCOME, expenseOrIncome);

    // Returns the row ID of newly inserted row, or -1 if an error occurred.
    return SqlDatabase.insert(DATABASE_TABLE, null, values);
}

public boolean deleteExpenseOrIncome(long rowId) {

    // Returns true if deleted, false otherwise.
    return SqlDatabase.delete(DATABASE_TABLE, TRANSACTION_ID + "=" + rowId, null) > 0;

}

public Cursor fetchAllExpensesAndIncomes() {

    // Returns a cursor over the list of all expenses/incomes.

    return SqlDatabase.query(DATABASE_TABLE, new String[] { TRANSACTION_ID,
            TRANSACTION_AMOUNT, TRANSACTION_DESCRIPTION, TRANSACTION_DATE, TRANSACTION_CATEGORY, TRANSACTION_CURRENCY, TRANSACTION_EXPENSE_OR_INCOME }, null, null, null, null,
            null);
}

public Cursor fetchSpecificExpenseOrIncome(long rowId) throws SQLException  {

        Cursor mCursor = SqlDatabase.query(true, DATABASE_TABLE, new String[] { 
                TRANSACTION_AMOUNT, TRANSACTION_DESCRIPTION, 
                TRANSACTION_DATE, TRANSACTION_CATEGORY, TRANSACTION_CURRENCY, TRANSACTION_EXPENSE_OR_INCOME },
                TRANSACTION_ID + "=" + rowId, null, null, null, null, null);

        if (mCursor != null) {
            mCursor.moveToFirst();
        }
            return mCursor;
    }

public boolean updateExpenseOrIncome(long rowId, int amount, String description, String date, String category, String currency_type, String expenseOrIncome) {

    // returns true if the expense/income was successfully updated, false otherwise.

    ContentValues values = new ContentValues();
    values.put(TRANSACTION_AMOUNT, amount);
    values.put(TRANSACTION_DESCRIPTION, description);
    values.put(TRANSACTION_DATE, date);
    values.put(TRANSACTION_CATEGORY, category);
    values.put(TRANSACTION_CURRENCY, currency_type);
    values.put(TRANSACTION_EXPENSE_OR_INCOME, expenseOrIncome);

    return SqlDatabase.update(DATABASE_TABLE, values, TRANSACTION_ID + "=" + rowId,  null) > 0;

}

public boolean deleteAllExpensesOrIncomes() {

    // true if any number of rows were deleted, false otherwise.

    return SqlDatabase.delete(DATABASE_TABLE, null, null) > 0;
}

public boolean deleteSpecificExpenseOrIncome(long rowId) {

    // true if a row is deleted, false otherwise.

    return SqlDatabase.delete(DATABASE_TABLE, TRANSACTION_ID + "=" + rowId, null) > 0;
}

}

1 个答案:

答案 0 :(得分:0)

由于这只是一个单用户安卓应用程序,我将跳过关于缓存计算值的一点(因为SQLite查找不是非常耗时)。但是,如果您认为需要额外的性能,则应该考虑使用第二个表来缓存重新运行计算时更新的计算值。

现在,回到你真正的问题:

假设您要编写一个基本函数,以根据您的交易和一些基本价值获得总余额。它可能看起来像这样:

public int getBalance(int baseValue) {
    String[] cols = new String[] {
        "SUM(" + TRANSACTION_AMOUNT + ")"
    };
    try {
        Cursor data = SqlDatabase.query(DATABASE_TABLE, cols, null, null, null, null, null);
        return data.getInt(data.getColumnIndexOrThrow(cols[0])) + baseValue;
    } catch(IllegalArgumentException e) {
        Log.e("MyApp", "Couldn't get balance", e);
        return 0;
    }
}

SUM(..) SQL函数返回列值的总和。

当然,这段代码不会立即生效,因为一方面,你有一个单独的expenseOrIncome列。有几种方法可以解决这个问题。首先:您可以重写事物以仅使用一列,并将负值视为费用,将正值视为收入。

或者,您可以执行两个查询。第一个选择你的收入,第二个选择你的开支。然后你从收入中扣除费用以获得余额。