Mik*_*ike 48 database sqlite android
我正在用数据库做我的第一个应用程序,我在理解onUpgrade函数时遇到了一些麻烦.我的数据库有一个包含项目和收藏列的表格,以便用户可以收藏项目.我看到的大多数实现只是删除表并重新构建它,但我不想这样做.我希望能够在表格中添加更多项目.
当应用程序通过Android市场升级时,数据库是否知道其版本号?那么我可以增加代码中的版本号,然后将其导出到市场,当用户第一次启动升级版本时,将调用onUpgrade吗?
如果是这种情况,我的onUpgrade只会从文件中提取并添加数据库项.这是一种标准的处理方式,还是有更好的方法在Android中处理它.我想尽可能保持标准.
谢谢
Pen*_*m10 108
Ok, before you run into bigger problems you should know that SQLite is limited on the ALTER TABLE command, it allows add and rename only no remove/drop which is done with recreation of the table.
You should always have the new table creation query at hand, and use that for upgrade and transfer any existing data. Note: that the onUpgrade methods runs one for your sqlite helper object and you need to handle all the tables in it.
So what is recommended onUpgrade:
if not exists (we are doing an upgrade, so the table might not exists yet, it will fail alter and drop)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)(This doesn't handle table downgrade, if you rename a column, you don't get the existing data transfered as the column names do not match).
.
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();
}
Run Code Online (Sandbox Code Playgroud)
pjv*_*pjv 39
在Pentium10的优秀答案旁边,这里有一些来自生活代码的好例子:
Android AOSP:com.android.providers.calendar.CalendarDatabaseHelper.java
Android AOSP:com.android.browser.BrowserProvider.java
OpenIntents记事本:org.openintents.notepad.NotePadProvider.java
感谢您澄清onUpgrade()不支持删除/删除语句@Pentium 10
对于那些想知道调用onUpgrade()的确切时刻的人,它是在调用getReadableDatabase()或getWriteableDatabase()期间.
对于那些不清楚如何确保它被触发的人......答案是:当提供给SqLiteOpenHelper的构造函数的数据库版本更新时,它会被触发.这是一个例子
public class dbSchemaHelper extends SQLiteOpenHelper {
private String sql;
private final String D_TAG = "FundExpense";
//update this to get onUpgrade() method of sqliteopenhelper class called
static final int DB_VERSION = 2;
static final String DB_NAME = "fundExpenseManager";
public dbSchemaHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
// TODO Auto-generated constructor stub
}
Run Code Online (Sandbox Code Playgroud)
现在...... onUpgrade()
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
sql = "ALTER TABLE " + fundExpenseSchema.Expense.TABLE_NAME + " ADD COLUMN " + fundExpenseSchema.Expense.FUNDID + " INTEGER";
arg0.execSQL(sql);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
36221 次 |
| 最近记录: |