ORMLite update of the database

前端 未结 4 747
陌清茗
陌清茗 2020-12-09 04:18

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 datab

4条回答
  •  渐次进展
    2020-12-09 05:03

    I don't like to drop database at every upgrade, or write an update code after I add each field, so ...

    I'm trying to do it like this:

    @Override
    public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
        ArrayList 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 getTableNames(SQLiteDatabase database){
        ArrayList 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();
    }
    

    I hope this code can be better.

    Here, i don't delete old tables and columns that were removed from dao's, and I don't create foreign fields (I'm not sure if i need it).

提交回复
热议问题