我的应用使用两个数据库(单独的文件)。为了处理这些数据库,我创建了两个扩展SQLiteOpenHelper的Helper类,每个数据库对应一个数据库。
我现在要添加第三个数据库并想知道是否需要创建另一个Helper类(如果我使用了第4个和第5个数据库,我还需要更多的Helper类),还是可以使用相同的Helper多个数据库的类?
我在尝试使用一个Helper类时遇到的问题是我无法看到如何将各个数据库文件的名称传递给Helper。目前,数据库的名称被硬编码为每个Helper类的静态字段,但是如果我只有一个Helper类,我需要能够在创建单独的Helper时将不同的名称传递给构造函数对象;问题是SQLiteOpenHelper构造函数似乎只是由Android调用,只有一个参数:Context。
答案 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个版本号。
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
)(这不会处理表降级,如果重命名列,则不会因列名不匹配而传输现有数据。)
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();
}