2012-08-12 103 views
1

我正在處理我的第一個Android應用程序,並且遇到了一個問題,我正在重複使用很多代碼片段來執行數據庫連接。我看到自己一遍又一遍地重寫相同的try/catch語句,但是我遇到了處理它的好方法。請看看這段代碼,你是否看到我缺少如何重構這個的明顯方式?是否有重構此SQLite數據庫處理程序的有效方法?

正如你所看到的那樣,這些方法通常只有1或2條線差異。下面是一個示例(所有其他try/catch代碼都是類似的):

遊標cursor = dbAdapter.fetchReceipts(timeFrom,timeTo);

Communicator.java

public ArrayList<Receipt> getReceipts(int limit) 
{ 
    ArrayList<Receipt> receiptList = null; 
    DbAdapter dbAdapter = new DbAdapter(context); 

    try 
    { 
     dbAdapter.open(); 
     Cursor cursor = dbAdapter.fetchReceipts(limit); 

     if (cursor != null) 
     { 
      receiptList = buildReceiptList(cursor); 
     } 

     dbAdapter.close(); 
    } 
    catch (SQLException e) 
    { 
     Log.d(context.getString(R.string.tag_receipttracker), e.getMessage()); 
     showToast(MESSAGE_COULD_NOT_OPEN); 
    } 
    return receiptList; 
} 

public ArrayList<Receipt> getReceipts(long timeFrom, long timeTo) 
{ 
    ArrayList<Receipt> receiptList = null; 
    DbAdapter dbAdapter = new DbAdapter(context); 

    try 
    { 
     dbAdapter.open(); 
     Cursor cursor = dbAdapter.fetchReceipts(timeFrom, timeTo); 

     if (cursor != null) 
     { 
      receiptList = buildReceiptList(cursor); 
     } 

     dbAdapter.close(); 
    } 
    catch (SQLException e) 
    { 
     Log.d(context.getString(R.string.tag_receipttracker), e.getMessage()); 
     showToast(MESSAGE_COULD_NOT_OPEN); 
    } 
    return receiptList; 
} 


public Receipt getLatestReceipt() 
{ 
    Receipt receipt = null; 
    Cursor cursor = null; 
    DbAdapter dbAdapter = new DbAdapter(context); 

    try 
    { 
     dbAdapter.open(); 
     cursor = dbAdapter.fetchLastReceipt(); 

     if (cursor.getCount() > 0) 
     { 
      receipt = buildReceipt(cursor); 
     } 

     dbAdapter.close(); 
    } 
    catch (SQLException e) 
    { 
     Log.d(context.getString(R.string.tag_receipttracker), e.getMessage()); 
     showToast(MESSAGE_COULD_NOT_OPEN); 
    } 
    return receipt; 
} 

public ArrayList<Receipt> searchReceipts(String query) 
{ 
    ArrayList<Receipt> receiptList = null; 
    DbAdapter dbAdapter = new DbAdapter(context); 

    try 
    { 
     dbAdapter.open(); 
     Cursor cursor = dbAdapter.searchReceiptName(query); 

     if (cursor != null) 
     { 
      receiptList = buildReceiptList(cursor); 
     } 

     dbAdapter.close(); 
    } 
    catch (SQLException e) 
    { 
     Log.d(context.getString(R.string.tag_receipttracker), e.getMessage()); 
     showToast(MESSAGE_COULD_NOT_OPEN); 
    } 

    return receiptList; 
} 

public boolean updateReceipt(Receipt receipt) 
{ 
    DbAdapter dbAdapter = new DbAdapter(context); 
    boolean result = false; 
    try 
    { 
     dbAdapter.open(); 
     result = dbAdapter.updateReceipt(receipt.getId(), receipt.getName(), receipt.getPhoto(), receipt.getTimestamp(), 
       receipt.getLocationLat(), receipt.getLocationLong(), receipt.getSum(), receipt.getTax(), receipt.getComment()); 
     showResult(result); 
     dbAdapter.close(); 
    } 
    catch (SQLException e) 
    { 
     Log.d(context.getString(R.string.tag_receipttracker), e.getMessage()); 
     showToast(MESSAGE_COULD_NOT_OPEN); 
    } 
    return result; 
} 

private boolean insertReceipt(Receipt receipt) 
{ 
    boolean result = false; 
    DbAdapter dbAdapter = new DbAdapter(context); 
    try 
    { 
     dbAdapter.open(); 
     result = dbAdapter.createReceipt(receipt.getName(), receipt.getPhoto(), receipt.getTimestamp(), receipt.getLocationLat(), 
       receipt.getLocationLong(), receipt.getSum(), receipt.getTax(), receipt.getComment()); 
     showResult(result); 
     dbAdapter.close(); 
    } 
    catch (SQLException e) 
    { 
     Log.d(context.getString(R.string.tag_receipttracker), e.getMessage()); 
     showToast(MESSAGE_COULD_NOT_OPEN); 
    } 
    return result; 
} 

DBAdapter.java

public Cursor fetchReceipt(long rowId) throws SQLException 
{ 

    Cursor cursor = db 
      .query(true, DATABASE_TABLE_RECEIPTS, new String[] { KEY_ROWID, KEY_NAME, KEY_PHOTO, KEY_TIMESTAMP, KEY_LOCATION_LAT, 
        KEY_LOCATION_LONG, KEY_SUM, KEY_TAX, KEY_COMMENT }, KEY_ROWID + "=" + rowId, null, null, null, null, null); 
    if (cursor != null) 
    { 
     cursor.moveToFirst(); 
    } 
    return cursor; 

} 

public Cursor fetchReceipts(long timeFrom, long timeTo) 
{ 
    Cursor cursor = db.query(true, DATABASE_TABLE_RECEIPTS, new String[] { KEY_ROWID, KEY_NAME, KEY_PHOTO, KEY_TIMESTAMP, 
      KEY_LOCATION_LAT, KEY_LOCATION_LONG, KEY_SUM, KEY_TAX, KEY_COMMENT }, KEY_TIMESTAMP + ">" + timeFrom + " AND " 
      + KEY_TIMESTAMP + "<" + timeTo, null, null, null, KEY_TIMESTAMP + " DESC", null); 
    if (cursor != null) 
    { 
     cursor.moveToFirst(); 
    } 
    return cursor; 
} 

public Cursor fetchLastReceipt() 
{ 
    Cursor cursor = db.query(true, DATABASE_TABLE_RECEIPTS, new String[] { KEY_ROWID, KEY_NAME, KEY_PHOTO, KEY_TIMESTAMP, 
      KEY_LOCATION_LAT, KEY_LOCATION_LONG, KEY_SUM, KEY_TAX, KEY_COMMENT }, null, null, null, null, KEY_ROWID + " DESC", "1"); 
    if (cursor != null) 
    { 
     cursor.moveToFirst(); 
    } 
    return cursor; 
} 

public Cursor searchReceiptName(String query) 
    { 
     Cursor cursor = db.query(DATABASE_TABLE_RECEIPTS, new String[] { KEY_ROWID, KEY_NAME, KEY_PHOTO, KEY_TIMESTAMP, KEY_LOCATION_LAT, 
       KEY_LOCATION_LONG, KEY_SUM, KEY_TAX, KEY_COMMENT }, KEY_NAME + " LIKE ?", new String[] { "%" + query + "%" }, null, null, 
       null); 
     if (cursor != null) 
     { 
      cursor.moveToFirst(); 
     } 
     return cursor; 
    } 

回答

1

首先,打開數據庫的時候,我會更好地使用這樣的:

if (db == null || !db.isOpen()) { 
db = getWritableDatabase(); //getReadableDatabase(); 
} 

,它會照顧你創建或打開數據庫,以防尚未完成。

對於方法的第一塊我想清楚地去somethink像:

public ArrayList<Receipt> searchReceipts(String query, DbAdapter _db, Cursor cursor) 
{ 
    ArrayList<Receipt> receiptList = null; 

    try 
    { 
     _db.open(); 

     if (cursor != null) 
     { 
      receiptList = buildReceiptList(cursor); 
     } 

     _db.close(); 
    } 
    catch (SQLException e) 
    { 
     Log.d(context.getString(R.string.tag_receipttracker), e.getMessage()); 
     showToast(MESSAGE_COULD_NOT_OPEN); 
    } 

    return receiptList; 
} 

這樣你只需要在之前創建適配器和光標在main方法傳遞下去他們,將執行所有呼叫的其餘邏輯。 我注意到有一種方法只是返回一個對象而不是數組。在這種情況下,您可以傳遞一個內部唯一對象的數組。

希望它有幫助。

讓我知道你的印象/更新。

+0

感謝您的回覆,但我不確定這確實會帶來很大的不同。我真正想要的是重用try/catch部分,因爲這是大部分重複的地方。將光標移動到參數中仍然意味着很多重複:/ – span 2012-08-13 15:27:56

+1

好吧,看起來相同的所有代碼現在只是寫入了。每次通話都會改變你的光標。你在這裏提到什麼重複?你有什麼建議? 我看了一下你的SQLite查詢來找到一些優化的機會,但它們看起來足夠大,可以分開。當我與數據庫進行通信時,通常會做什麼我使用一種獲取方法並使用另一種方法來編寫參數化乾草SQLiteDatabase.query。這對你來說可能也是一個研究點。 – 2012-08-13 19:37:40

+0

謝謝Jose,下次我允許自己進行一些重構時,我會更深入地研究這一點。會讓你知道它是如何發生的:) – span 2012-08-15 07:30:14

相關問題