数据库的更新ORMLite(ORMLite update of the database)

2019-07-04 19:52发布

I'm actually developing an app which is using ORMLite library (which is wonderful btw) but I'm a beginner using it.

I have a question about the update of the database inside the device.

Let's say that someone download my app on the Google Play. Few months later I will certainly populate some tables with new entries.

When this person is doing an update of the app, how can I just update the database with my new entries and keep the old ones inside it.

To be more clear, imagine that the user answered questions in my app. When I will introduce new questions, how can I insert them in the db when he updates my app and keep the questions that have already been answered ?

Answer 1:

当这个人是做应用程序的更新,我怎么能只与我的新条目更新数据库,并保持里面的旧的。

我们的想法是使用传递到版本号onUpgrade(...)方法。 随着ORMLite的OrmLiteSqliteOpenHelper.onUpgrade(...)方法接受一个oldVersionnewVersion号。 然后,您可以编写代码的转换到你的应用程序,它能够将数据从旧格式转换和更新模式。

欲了解更多信息,请参阅关于该主题的ORMLite文档:

http://ormlite.com/docs/upgrade-schema

要报价,你可以做类似如下:

if (oldVersion < 2) {
  // we added the age column in version 2
  dao.executeRaw("ALTER TABLE `account` ADD COLUMN age INTEGER;");
}
if (oldVersion < 3) {
  // we added the weight column in version 3
  dao.executeRaw("ALTER TABLE `account` ADD COLUMN weight INTEGER;");
}

如果现有的数据,你需要转换,那么你应该尽可能做转换的SQL。

另一种方法是有一个Account实体和OldAccount实体指向同一个表名。 然后,你可以在阅读OldAccount使用实体oldAccountDao ,将它们转换为Account实体,然后利用更新它们accountDao回到同一个表。 你必须小心,这里对象缓存。



Answer 2:

我做这种方式:

@Override
public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {

    switch (oldVersion) {
    case 1:
        updateFromVersion1(database, connectionSource, oldVersion, newVersion);
        break;
    case 2:
        updateFromVersion2(database, connectionSource, oldVersion, newVersion);
        break;
    default:
        // no updates needed
        break;
    }

}

private void updateFromVersion1(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
    // do some stuff here
    onUpgrade(database, connectionSource, oldVersion + 1, newVersion);
}

private void updateFromVersion2(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
    // do some stuff here
    onUpgrade(database, connectionSource, oldVersion + 1, newVersion);
}

这将逐步更新的用户数据库独立于该数据库版本,他来了。



Answer 3:

小资料,目前尚不清楚是否变化有表结构。

a)如果你不改变数据库结构。

1在你的程序与目前的新版本中,当您启动(在喜好EG)检查以前保存的版本(见PackageManager.getPackageInfo)

保存= 0 - 用户刚安装的新版本

保存<电流 - 用户更新程序

2添加新的数据到基

3保存喜好当前版本

b)如果表结构发生了改变(添加或删除字段)

1增加数据库的版本号(请参阅您的扩展OrmLiteSqliteOpenHelper类)

2当用户第一次运行到你的程序,方法“onUpgrade”将被调用(在扩展OrmLiteSqliteOpenHelper类),这将被转移到新老版本号。

  • 阅读在缓存中现有的数据(TEMP)
  • 重新创建表
  • 从添加缓存中的数据+新数据


Answer 4:

我不喜欢在每次升级到删除数据库,或者以后我添加的每个字段编写一个更新代码,所以...

我试图做这样的:

@Override
public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
    ArrayList<String> tableNames = getTableNames(database);
    for (Class clazz : daoClasses) {
        try {
            Annotation annotation = clazz.getAnnotation(DatabaseTable.class);
            if (annotation != null && annotation instanceof DatabaseTable) {
                String tableName = ((DatabaseTable) annotation).tableName();
                if (tableName.isEmpty()) {
                    tableName = clazz.getSimpleName().substring(0, 1).toLowerCase() + clazz.getSimpleName().substring(1);
                }
                if(!tableNames.contains(tableName)){
                    TableUtils.createTable(connectionSource, clazz);
                } else {
                    addColumns(database, tableName, clazz);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

private ArrayList<String> getTableNames(SQLiteDatabase database){
    ArrayList<String> tableNames = new ArrayList<>();
    Cursor cursor = database.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
    if (cursor.moveToFirst()) {
        while ( !cursor.isAfterLast() ) {
            tableNames.add(cursor.getString(0));
            cursor.moveToNext();
        }
    }
    cursor.close();
    return tableNames;
}

private void addColumns(SQLiteDatabase database, String tableName, Class clazz){
    Cursor mCursor = database.rawQuery("SELECT * FROM " + tableName + " LIMIT 0", null);
    for (Field field : clazz.getDeclaredFields()) {
        try {
            DatabaseField annotationField = field.getAnnotation(DatabaseField.class);
            if (annotationField != null && !annotationField.foreign()){
                String columnName = field.getName();
                boolean hasColumn = mCursor.getColumnIndex(columnName) != -1;
                if (!hasColumn) {
                    String columnType = field.getType().getSimpleName();
                    if(columnType.equals(String.class.getSimpleName())){
                        columnType = "TEXT";
                    } else {
                        columnType = columnType.toUpperCase();
                    }
                    database.execSQL(MessageFormat.format("ALTER TABLE `{0}` ADD COLUMN {1} {2};", tableName, columnName, columnType));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    mCursor.close();
}

我希望这段代码可以更好。

在这里,我不删除DAO的被拆除旧表和列,我不创建外域(我不知道如果我需要的话)。



文章来源: ORMLite update of the database