使用自增主键迁移 Room 数据库
Migrate Room database with Autoincrement Primary Key
我有一个实体用户,它在保存到数据库时自动创建 UID。
我正在尝试迁移 table 但用户的旧 UID 不迁移,这是一个严重的问题。
如何保留旧的 UID?
ContentValues cv = null;
try {
Cursor c = database.query("SELECT * FROM users");
if (c.moveToFirst()) {
cv = new ContentValues();
do {
cv.put("uid", c.getLong(c.getColumnIndex("uid")));
cv.put("name", c.getString(c.getColumnIndex("name")));
} while (c.moveToNext());
}
} catch (Exception ex) {
Logger.ex(TAG, ex);
}
database.execSQL("DROP TABLE IF EXISTS 'users'");
database.execSQL("CREATE TABLE IF NOT EXISTS `users` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`name` TEXT)");
if (cv != null)
database.insert("users", 0, cv);
您最多只能保存 1 行。
使用上面的方法,您可能需要一个 ContentValue 数组来保存多个用户。
例如
ArrayList<ContentValues> cvlist = new ArrayList<>();
Cursor c = database.query("SELECT * FROM users");
while(c.moveToNext) {
ContentValue cv = new ContentValue();
cv.put("uid",c.getLong(c.getColumnIndex("uid")));
cv.put("name", c.getString(c.getColumnIndex("name")));
cvlist.add(cv);
}
database.execSQL("DROP TABLE IF EXISTS 'users'");
database.execSQL("CREATE TABLE IF NOT EXISTS `users` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`name` TEXT)");
for(ContentValue cv: cvlist) {
database.insert("users", 0, cv);
}
但是,您可以使用以下方法简化上述内容:-
database.execSQL("CREATE TABLE IF NOT EXISTS `temp_users` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`name` TEXT)");
database.execSQL("INSERT INTO `temp_users` SELECT * FROM `users`");
database.execSQL("ALTER TABLE `users` RENAME TO `original_users`");
database.execSQL("ALTER TABLE `temp_users` RENAME TO `users`");
database.execSQL("DROP TABLE IF EXISTS `original_users`");
这将创建具有不同名称 (temp_users) 的新 table,将原始 table 中的所有行复制到新 table 中。然后它重命名原来的 table,然后将新的 table 重命名为实际名称(所以现在变成它使用的实际 table),最后删除重命名的原始 table.
(您可以删除原来的 table 而不是更改它的名称,但是上面的更安全)。
- 注意以上为原理代码,尚未运行或测试,因此可能包含一些错误。
我有一个实体用户,它在保存到数据库时自动创建 UID。
我正在尝试迁移 table 但用户的旧 UID 不迁移,这是一个严重的问题。
如何保留旧的 UID?
ContentValues cv = null;
try {
Cursor c = database.query("SELECT * FROM users");
if (c.moveToFirst()) {
cv = new ContentValues();
do {
cv.put("uid", c.getLong(c.getColumnIndex("uid")));
cv.put("name", c.getString(c.getColumnIndex("name")));
} while (c.moveToNext());
}
} catch (Exception ex) {
Logger.ex(TAG, ex);
}
database.execSQL("DROP TABLE IF EXISTS 'users'");
database.execSQL("CREATE TABLE IF NOT EXISTS `users` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`name` TEXT)");
if (cv != null)
database.insert("users", 0, cv);
您最多只能保存 1 行。
使用上面的方法,您可能需要一个 ContentValue 数组来保存多个用户。
例如
ArrayList<ContentValues> cvlist = new ArrayList<>();
Cursor c = database.query("SELECT * FROM users");
while(c.moveToNext) {
ContentValue cv = new ContentValue();
cv.put("uid",c.getLong(c.getColumnIndex("uid")));
cv.put("name", c.getString(c.getColumnIndex("name")));
cvlist.add(cv);
}
database.execSQL("DROP TABLE IF EXISTS 'users'");
database.execSQL("CREATE TABLE IF NOT EXISTS `users` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`name` TEXT)");
for(ContentValue cv: cvlist) {
database.insert("users", 0, cv);
}
但是,您可以使用以下方法简化上述内容:-
database.execSQL("CREATE TABLE IF NOT EXISTS `temp_users` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
"`name` TEXT)");
database.execSQL("INSERT INTO `temp_users` SELECT * FROM `users`");
database.execSQL("ALTER TABLE `users` RENAME TO `original_users`");
database.execSQL("ALTER TABLE `temp_users` RENAME TO `users`");
database.execSQL("DROP TABLE IF EXISTS `original_users`");
这将创建具有不同名称 (temp_users) 的新 table,将原始 table 中的所有行复制到新 table 中。然后它重命名原来的 table,然后将新的 table 重命名为实际名称(所以现在变成它使用的实际 table),最后删除重命名的原始 table.
(您可以删除原来的 table 而不是更改它的名称,但是上面的更安全)。
- 注意以上为原理代码,尚未运行或测试,因此可能包含一些错误。