我看到了关于使用绿色数据(这里)的模式升级/迁移的另一个问题。
在进行模式升级时,这个答案中有很多链接可供使用--但是,对于如何正确迁移数据,您并没有实际操作的示例,而且我也很难找到任何东西。
在我的例子中,我的迁移是非常直接的--我不希望转换任何现有的数据,我只需要向我的模式中添加一些新的表,我想这是一个相当常见的情况。
最好举一个具体的例子。。
如果greenDao提供了一个类似于DevOpenHelper的类,只需添加以前在模式中不存在的新表/列,而不首先删除现有的tabes/data,那就太棒了。
发布于 2013-05-05 15:43:08
我终于有时间亲自钻研这个问题,并意识到在旧表中保留数据很容易添加一个新表。
免责声明:虽然我意识到这个实现是特定于我的场景,但我认为这对像我这样专门使用Android工具(greenDao)来处理安卓上的SQLite的人是有帮助的。我知道,对于那些从一开始就编写了自己的表创建查询的人来说,这是很常见的,但是对于那些没有在SQLite上使用DB的人来说,我认为这个例子会很有帮助。
回答:,您可以修改DevOpenHelper内部类,也可以创建自己的类。为了保持示例的简单性,我暂时选择编辑DevOpenHelper --但是,请注意,如果您重新生成您的greendao类,DevOpenHelper将被覆盖。最好像"MyOpenHelper“那样创建您自己的类,然后使用它。
在进行更改之前,DevOpenHelper.onUpgrade如下所示:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
}与其删除所有表,不如看看由createAllTables自动生成的GreenDao方法。
重写onUpgrade以检查"oldVersion“是否是您想要升级的对象,然后只调用”新“表的createTable方法。下面是我的onUpgrade方法现在的样子:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " +
//Going from older schema to new schema
if(oldVersion == 3 && newVersion == 4)
{
boolean ifNotExists = false;
//Leave old tables alone and only create ones that didn't exist
//in the previous schema
NewTable1Dao.createTable(db, ifNotExists);
NewTable2Dao.createTable(db, ifNotExists);
NewTable3Dao.createTable(db, ifNotExists);
NewTable4Dao.createTable(db, ifNotExists);
}
else
{
dropAllTables(db, true);
onCreate(db);
}
}添加一个新列也是类似的,但您必须编写一些SQL,或者查看来自greenDao的自动生成的generated语句并利用这些语句。
若要向现有表(NEW_COLUMN )添加单个新列(假设它是整数类型),请执行以下操作:
db.execSQL("ALTER TABLE 'EXISTING_TABLE' ADD 'NEW_COLUMN' INTEGER");现在对我来说,我所需要做的就是添加新的表,这样它就会变得非常直接。希望其他人发现这是有用的。
发布于 2014-09-23 09:16:44
我做了一种稍微不同的方法来自动处理更新,不管前面的用户来自哪里。首先,我创建了一个在onUpgrade上实现SQLDatabase方法的类
public abstract class AbstractMigratorHelper {
public abstract void onUpgrade(SQLiteDatabase db);
}之后,我将从这个类继承所有的移民助手。
我会写其中一个例子
public class DBMigrationHelper5 extends AbstractMigratorHelper {
/* Upgrade from DB schema x to schema x+1 */
public void onUpgrade(SQLiteDatabase db) {
//Example sql statement
db.execSQL("ALTER TABLE user ADD COLUMN USERNAME TEXT");
}
}在此之后,您需要在升级时实际调用的类上实现逻辑,在这个类中,您需要删除以前的DevOpenHelper,以便定制一个类似于下面的类
public static class UpgradeHelper extends OpenHelper {
public UpgradeHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}
/**
* Here is where the calls to upgrade are executed
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/* i represent the version where the user is now and the class named with this number implies that is upgrading from i to i++ schema */
for (int i = oldVersion; i < newVersion; i++) {
try {
/* New instance of the class that migrates from i version to i++ version named DBMigratorHelper{version that the db has on this moment} */
AbstractMigratorHelper migratorHelper = (AbstractMigratorHelper) Class.forName("com.nameofyourpackage.persistence.MigrationHelpers.DBMigrationHelper" + i).newInstance();
if (migratorHelper != null) {
/* Upgrade de db */
migratorHelper.onUpgrade(db);
}
} catch (ClassNotFoundException | ClassCastException | IllegalAccessException | InstantiationException e) {
Log.e(TAG, "Could not migrate from schema from schema: " + i + " to " + i++);
/* If something fail prevent the DB to be updated to future version if the previous version has not been upgraded successfully */
break;
}
}
}
}因此,如果您很小心地命名了您的迁移助手(即MigrationHelper5完成了从模式5到模式6的迁移),那么您可以实现这个逻辑,然后在每个MigratorHelper类中使用您需要实现的所有execSQL代码来实现execSQL调用。
最后,请注意,如果您正在使用proguard,那么逐个类查找名称的方法可能无法工作,因为在混淆代码时会更改类名。您可能需要考虑在proguard配置文件上添加一个异常(pro保密规则. from ),以排除从AbstractMigratorHelper扩展的任何类。
# Avoid errors when upgrading database migrators
-keep public class * extends yourpackage.locationofyourclass.AbstractMigratorHelper发布于 2013-08-16 06:56:18
我的做法略有不同。
我将新的@DatabaseTable类和任何@DatabaseField添加到现有的@DatabaseTable类中,并运行DatabaseConfigUtil。
然后,我将向我的DatabaseUpgrader类添加一个新的方法,并修改我的DatabaseHelper,更改DATABASE_VERSION值和onUpdate方法
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
private static final int DATABASE_VERSION = 3;
@Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
switch (oldVersion) {
case 1:
DatabaseUpdater.from1to2(connectionSource);
DatabaseUpdater.from2to3(connectionSource);
break;
case 2:
DatabaseUpdater.from2to3(connectionSource);
break;
default:
onCreate(db);
}
}
}
public static DatabaseHelper getInstance() {
return DatabaseHelper.mHelper;
}
public static void setInstance(Context context) {
DatabaseHelper.mHelper = new DatabaseHelper(context);
}
…
}然后在DatabaseUpdater类中
public class DatabaseUpdater {
private static final String TAG = "DatabaseHelper";
public static void from1to2(ConnectionSource connectionSource) {
try {
DatabaseHelper helper = DatabaseHelper.getInstance();
//Example add a table
TableUtils.createTable(connectionSource, AnotherEntity.class);
} catch (SQLException e) {
Log.e(TAG, "Error upgrading database to v2: ", e);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
}
public static void from2to3(ConnectionSource connectionSource) {
try {
DatabaseHelper helper = DatabaseHelper.getInstance();
//Example add a field to a table
RuntimeExceptionDao<MyEntity, Integer> myDao = helper.getMyDao();
diaryDao.executeRaw("ALTER TABLE myEntity ADD firstNewField");
diaryDao.executeRaw("ALTER TABLE myEntity ADD anotherNewField");
} catch (SQLException e) {
Log.e(TAG, "Error upgrading database to v3: ", e);
}
}
}https://stackoverflow.com/questions/16154113
复制相似问题