Android:我可以为多个数据库文件使用一个SQLiteOpenHelper类吗?

时间:2010-11-20 17:31:35

标签: android database sqlite class-design

我的应用使用两个数据库(单独的文件)。为了处理这些数据库,我创建了两个扩展SQLiteOpenHelper的Helper类,每个数据库对应一个数据库。

我现在要添加第三个数据库并想知道是否需要创建另一个Helper类(如果我使用了第4个和第5个数据库,我还需要更多的Helper类),还是可以使用相同的Helper多个数据库的类?

我在尝试使用一个Helper类时遇到的问题是我无法看到如何将各个数据库文件的名称传递给Helper。目前,数据库的名称被硬编码为每个Helper类的静态字段,但是如果我只有一个Helper类,我需要能够在创建单独的Helper时将不同的名称传递给构造函数对象;问题是SQLiteOpenHelper构造函数似乎只是由Android调用,只有一个参数:Context。

2 个答案:

答案 0 :(得分:17)

当然,你可以。这只是你的Helper类设计的问题。您只需将DB的名称传递给Helper类构造函数(以及必需的Context实例),而不是硬编码:

public class DBOpenHelper extends SQLiteOpenHelper {

    public DBOpenHelper(Context context, String dbName, int dbVersion) {
        super(context, dbName, null, dbVersion);
    }
...
}

答案 1 :(得分:2)

您需要一个抽象类来实现此处描述的升级过程。然后,为每个表扩展此抽象类。在您的抽象类中,您必须以某种方式存储表(列表,硬编码),因此当onUpgrade触发您迭代表项时,对于每个表项,您将执行所描述的步骤。它们将自我升级,保留所有现有细节。请注意,onUpgrade事件每个数据库只触发一次,这就是为什么你需要迭代所有表来进行所有表的升级。您在所有数据库中只维护了1个版本号。

  • 的BeginTransaction
  • 使用if not exists运行表创建(我们正在进行升级,因此表可能尚未存在,它将无法更改和删除)
  • 列出现有列List<String> columns = DBUtils.GetColumns(db, TableName);
  • 备用表(ALTER table " + TableName + " RENAME TO 'temp_" + TableName
  • 创建新表(最新的表创建架构)
  • 获取与新列的交集,这次是从升级后的表格中取得的列(columns.retainAll(DBUtils.GetColumns(db, TableName));
  • 恢复数据(String cols = StringUtils.join(columns, ","); db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TableName, cols, cols, TableName));
  • 删除备用表(DROP table 'temp_" + TableName
  • setTransactionSuccessful

(这不会处理表降级,如果重命名列,则不会因列名不匹配而传输现有数据。)

public static List<String> GetColumns(SQLiteDatabase db, String tableName) {
    List<String> ar = null;
    Cursor c = null;
    try {
        c = db.rawQuery("select * from " + tableName + " limit 1", null);
        if (c != null) {
            ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
        }
    } catch (Exception e) {
        Log.v(tableName, e.getMessage(), e);
        e.printStackTrace();
    } finally {
        if (c != null)
            c.close();
    }
    return ar;
}

public static String join(List<String> list, String delim) {
    StringBuilder buf = new StringBuilder();
    int num = list.size();
    for (int i = 0; i < num; i++) {
        if (i != 0)
            buf.append(delim);
        buf.append((String) list.get(i));
    }
    return buf.toString();
}