2011-12-23 49 views
1

嗯,這是一個關於Android SQL Lite數據庫的「最佳實踐」的問題。Android數據庫高級生命週期

我得到了我DBHandler與所謂DBHelper這樣一個內部類創建一個SQLiteDatabase

private final DBHelper dbhelper; 
    SQLiteDatabase db = dbhelper.getReadableDatabase(); 

    // Call the helper 
    private static class DBHelper extends SQLiteOpenHelper { 

    DBHelper(Context context){  
     super(context, DB_NAME, null, DB_VERSION); 
    } 
     @Override 
     public void onCreate(SQLiteDatabase db){ 
      // create Table01  
      String sql = "create table " + "... SQL stuff here";  
      db.execSQL(sql); 
     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ 
      db.execSQL("drop table if exists " + Table01); 
      onCreate(db); 
     } 
    } 

另外,DBHandler提供功能用於添加/檢索數據到/從象例如表這個:

public void insertOrIgnore(String table, ContentValues values){ 
    SQLiteDatabase db = this.dbhelper.getWritableDatabase(); 
    try{ 
     db.insertOrThrow(table, null, values); 
    } 
    catch (SQLException e){ 
     e.printStackTrace(); 
     Log.e(TAG, e.toString()); 
    } 
    finally { 
     db.close(); 
    } 
} 

public Cursor getTable1(){ 
    SQLiteDatabase db = dbhelper.getReadableDatabase(); 
    Cursor cursor = db.query(Table1, null, null, null, null, null, TABEL_ID + " ASC"); 

    return cursor; 
} 

當我需要從數據庫中的數據我創建一個DBHandler對象並使用它的方法。

因此,在第一次應用程序運行時,我調用insertOrIgnore方法並添加我想稍後使用的數據。 每當我對數據庫進行更改時,我需要卸載APP並重新安裝,以使更改生效。這很糟糕,所以我想用DB_VERSION來處理那些東西。在更改數據庫(模式或數據)之後,我將DB_VERSION ID更改爲更高的數字。

所以我的問題是:

  1. 如果newDBversion> oldDBversion,SQLiteDatabase不到風度使用的onCreate不過的onUpdate。這工作正常,但只有模式更新 ,它會導致空白表。我想知道最佳實踐,所以 之後onUpdate數據方法從DBHandler被再次調用。 請注意,DBHelper是內部類 DBHandler
  2. 對於我的理解SQLiteDatabase onCreate方法是隻有調用如果數據庫不存在和onUpdate方法是 只有調用如果newDBversion> oldDBversion,是否正確?
  3. DBHandler必須是靜態的還是單身?還是沒有,因爲類自己處理多個讀/寫?

我開朗了更好的解決方案,但是從我在網上和一些Android的書中發現,那種將數據添加到SQL數據庫的就是它做的方式。但沒有人解釋如何更新數據(不是模式,每當dbversion發生變化時自動完成)

回答

0

我可以回答第三個問題,因爲我在這個問題上研究了一些。我決定,這是好事,有定義這些類的方式如下(看我的代碼)

public class DbWordsAdapter { 

private static final String TAG = DbWordsHelper.class.getSimpleName(); 
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; 

private static DbWordsHelper dbWordsHelper; 
private Context context; 
private SQLiteDatabase mDb; 

// database constants 
private static final String DB_NAME = "words.db"; 
private static final int DB_VERSION = 1; 
private static final String TABLE_WORDS = "words"; 

// database columns names 
public static final String C_ID = BaseColumns._ID; 
public static final String C_WORD = "word"; 
public static final String C_EXPLANATION = "explanation"; 
public static final String C_CREATION_DATE = "creation_date"; 

//Sql Statements 
static final String CREATE_TABLE_WORDS = "create table " + TABLE_WORDS 
     + "(" + C_ID + " integer primary key autoincrement, " + C_WORD 
     + " text not null, " + C_EXPLANATION + " text, " 
     + C_CREATION_DATE + " date not null)"; 
static final String DROP_TABLE_WORDS = "drop table if exists" 
     + TABLE_WORDS;  
static final String[] ALL_COLUMNS = { C_ID, C_WORD, C_EXPLANATION, 
     C_CREATION_DATE }; 
static final String ORDER_BY_DATE = C_CREATION_DATE + " desc"; 
static final String ORDER_BY_ALPH = C_WORD + " asc"; 
static final String ORDER_BY_RANDOM = "random() limit 1"; 


/* 
* Inner class that manages database creation and management 
*/ 
private static class DbWordsHelper extends SQLiteOpenHelper { 

    private DbWordsHelper(Context context) { 
     super(context, DB_NAME, null, DB_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     Log.d(TAG, "SqlCreate Statement: " 
       + CREATE_TABLE_WORDS); 

     try { 
      db.execSQL(CREATE_TABLE_WORDS); 
     } catch (SQLException e) { 
      Log.e(TAG, "Error while creating database" + TABLE_WORDS, e); 
     } 

    } 

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

     // Here in the future should be method that change the schema of the 
     // database. Now we just delete 
     try { 
      db.execSQL(DROP_TABLE_WORDS); 
     } catch (SQLException e) { 
      Log.e(TAG, "Error while updating database" + TABLE_WORDS, e); 
     } 

     onCreate(db); 

    } 
} 

public DbWordsAdapter(Context context) { 
    this.context = context; 
} 

public DbWordsAdapter open() { 
    if (dbWordsHelper == null) { 
     dbWordsHelper = new DbWordsHelper(context); 
    } 
    mDb = dbWordsHelper.getWritableDatabase(); 
    return this; 
} 

public void close() { 
    dbWordsHelper.close(); 
    dbWordsHelper = null; 
} 

// 
//Following methods implement CRUD operations for this database 
// 

/* 
* This method creates new Word in the database. 
* 
* @param word that we create 
* 
* @param explanation of the word 
* 
* @return id of the word 
*/ 
public long createWord(String word, String explanation) { 
    Log.d(TAG, "createWord method"); 
    ContentValues newWord = createValue(word, explanation, 
      createDateString(new Date())); 
    return mDb.insert(TABLE_WORDS, null, newWord); 
} 

在你的應用程序,你只需撥打dbWordsAdapter.open();那麼你的數據庫的事務(例如,dbWordsAdapter.createWord(word, explanation))的適當位置和關閉數據庫。因此,對於活動,您可以在onResume()方法中打開數據庫並關閉onPause()

考慮到第二個問題,我認爲您是可行的。

對於第一個問題我不知道。也許很高興看到這是如何在其他應用程序中實現的。

更新:回答第一個問題 在文檔和其他資源中,我找到了有關數據庫更新的信息。您可以使用sql語句alter table將新列插入到數據庫中。

如果添加新列,可以使用ALTER TABLE將它們插入到實時表中。如果重命名或刪除列,則可以使用ALTER TABLE重命名舊錶,然後創建新表,然後使用舊錶的內容填充新表。

所以,基本上算法中的onUpdate更新應該是以下幾點:

  1. 首先,根據oldVersion和NEWVERSION你定義什麼 應更新。
  2. 然後如果你只是想添加列,然後你調用ALTER TABLE ADD COLUMN sql語句。這有一些限制。你可以在 找到他們here
  3. 刪除和重命名,你可以使用下面的建議:如果你 重命名或刪除列,您可以使用ALTER TABLE來重命名舊 表,然後創建新表,然後填充新表 用的內容舊桌子。

希望這有助於!

+0

聖誕節後會看看它,感謝迄今和快樂hollidays! – masi 2011-12-24 12:43:25

+0

好。因爲第一個問題對我來說是最重要的,所以我仍然不能按照我想要的方式工作:-( 一些實現示例會很好,但是我找不到任何好的。 – masi 2011-12-30 00:50:27

+0

我已經爲第一個問題添加了提示。 – Yury 2011-12-30 07:17:22