2011-12-23 106 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