2013-08-18 162 views

回答

6

這是一個相當廣泛的問題,並且取決於您的經驗和使用水平。

但常見的做法是創建自己的ContentProvider,它將抽象訪問數據庫。通過這種方式,您可以使用Uri執行選擇/更新/刪除/插入查詢。

對於SQLite數據庫本身,請使用SQLiteOpenHelper來抽象SQLite數據庫的創建和升級。這將允許您升級數據庫,而不會讓用戶以一種簡單的方式丟失所有數據。

我可以在我的一個老項目中附加一段代碼,這些代碼可以幫助您開始。但是實施整個事情可能超出單個問題/答案的範圍。

public class MyServiceProvider extends ContentProvider { 
    private SQLiteDatabase db; 

    @Override 
    public boolean onCreate() { 
     // Initialize the database and assign it to the private variable 
     MyDatabaseHelper sqlHelper = new MyDatabaseHelper(getContext()); 
     db = sqlHelper.getReadableDatabase(); 

     return (db == null)?false:true; 
    } 

    @override 
    Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
     // handle the query here, form it, do your checks and then access the DB 
     db.query(....); 
    } 
} 

class MyDatabaseHelper extends SQLiteOpenHelper { 
    private static final String LOG_TAG = "MyAppTag"; 
    private static final String DB_NAME = "Databasename"; 
    private static final String TABLE_NAME = "Tablename"; 
    private static final int DATABASE_VERSION = 2; 
    public static MyServiceProvider.CONTENT_URI = Uri.parse("content://com.mycompany.myApp.MyAppService/myTableOrIdentifier"); 

    public MyDatabaseHelper(Context context){ 
     super(context, DB_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     String sql = "CREATE TABLE IF NOT EXISTS ...."; 
     db.execSQL(sql); 
    } 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     // Here you can perform updates when the database structure changes 
     // Begin transaction 
     db.beginTransaction(); 

     try { 
      if(oldVersion<2){ 
       // Upgrade database structure from Version 1 to 2 
       String alterTable = "ALTER ...."; 

       db.execSQL(alterTable); 
       Log.i(LOG_TAG,"Successfully upgraded to Version 2"); 
      } 
      // This allows you to upgrade from any version to the next most 
      // recent one in multiple steps as you don't know if the user has 
      // skipped any of the previous updates 
      if(oldVersion<3){ 
       // Upgrade database structure from Version 2 to 3 
       String alterTable = "ALTER ...."; 

       db.execSQL(alterTable); 
       Log.i(LOG_TAG,"Successfully upgraded to Version 3"); 
      } 

      // Only when this code is executed, the changes will be applied 
      // to the database 
      db.setTransactionSuccessful(); 
     } catch(Exception ex){ 
      ex.printStackTrace(); 
     } finally { 
      // Ends transaction 
      // If there was an error, the database won't be altered 
      db.endTransaction(); 
     } 
    } 
} 

然後您可以使用遊標與數據庫進行交互。

ContentResolver contentResolver = getContentResolver(); 
... 
Cursor c = contentResolver.query(
     // The Uri results in content://com.mycompany.myApp.MyAppService/myTableOrIdentifier/someId 
     Uri.withAppendedPath(MyServiceProvider.CONTENT_URI, someId), 
     new String[] { 
      // only get fields we need! 
      "MyDbFieldIneed" 
     }, 
     null, null, null); 

這將返回一個Cursor這將可以遍歷並獲得滿意的結果。這也是Android實現的大部分內容(即通過Uri和Cursor從地址簿中獲取地址)。

編輯: 我意識到鏈接很難看到與代碼的亮點。在這裏你需要重要課程的鏈接。

編輯2: 此外,如果你有多個表工作,UriMatcher是一個重要的源太

+0

謝謝。你能告訴我一個如何聲明contentResolver對象的例子嗎? –

+0

這很容易。 'getContentResolver()'是'Context'的一種方法,其中'Activity'派生自(實際上'Activity'派生自'ContextThemeWrapper',派生自'ContextWrapper',派生自'Context')。因此,一個簡單的'ContentResolver contentResolver = getContentResolver();''ContentProvider'將爲它做 – Tseng

1

Which is the best manner for this?
您需要使用SQLite其自帶的Android。每個Android應用都可以擁有自己的數據庫。

which class sub I use, subclass, reimplement,
您需要擴展SQLiteOpenHelper類決定了你的數據庫的名稱,它是如何升級/降級,該表的結構以及等等。它還定義了獲取對數據庫的引用的方法。

是的,很多資源都在那裏,而不是大腦和質量的資源。下面是一些我喜歡:
SQLite and COntentProvider by Lars Vogel
Prof. Gustin's Android Tutorials

至於你的問題Best practices for Android databases所有我能說的是,所有適用於SQL數據庫的最佳做法,適用於這裏就像規範化的標題等

4

我想使用SQLite數據庫的最佳方式是使用ContentProviders。當你搜索它時,你會看到ContentProvider API非常複雜。但是有一個非常好的庫,使得這個過程非常簡單。它被稱爲ProviGen,你可以在下面的鏈接中找到關於它的詳細信息。

https://github.com/TimotheeJeannin/ProviGen

這是非常容易使用。您只需創建一個Contract類,您將在其中使用註釋指出您需要在數據庫中使用哪些列,並且它會自動創建所有內容。我甚至可以在一個數據庫中創建多個表。

+0

+1。但我不同意他們很複雜。一旦你得到它,它非常簡單。首先需要多一點的代碼,但這對大多數模式都是有效的。 MVVM/MVC模式首先需要一些代碼才能開始,但是它們都是有效的模式,並且稍後易於維護。 – Tseng

+0

當你在連接到ContentProvider的SQLite數據庫中有2或3個表時,事情變得更加複雜。 ProviGen會自動完成。 – tasomaniac

2

我會說最好的做法是使用一個框架,它將爲您完成大部分工作。我個人更喜歡使用數據庫進行ORM映射,因此我建議嘗試一些ORM框架。我知道的最好的是OrmLite。作者還回答了關於SO的問題,這可能非常有用。

但是,如果你不想使用它,你應該通過閱讀這些文章開始:

相關問題