android數據庫的升級的寫法

jopen 10年前發布 | 14K 次閱讀 Android開發 移動開發 Android

在基類的table中加入upgrade操作:

    public abstract class DbBaseTable {  

        private static final String TAG = "DbBaseTable";  

        /** 
         * @return the DB table name 
         */  
        abstract String getName();  

        /** 
         * Creates the DB table according to the DB scheme 
         *  
         * @param db 
         */  
        abstract void onCreate(SQLiteDatabase db);  

        void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion, String tempName) {  

            //Rename old table to temporary name  
        DbUtils.renameTable(db, getName(), tempName);  

            //Create clear table according to the new scheme  
           onCreate(db); 
            //Copy content of the matching columns from the old table to the new one  
          joinColumns(db, tempName, getName()); 

            //Delete old table  
          DbUtils.dropTable(db, tempName); 

            //這個是更新一些表的內容  
            initTableContent(db);  
        }  

        void initTableContent(SQLiteDatabase db) {  
        }  

        void joinColumns(SQLiteDatabase db, String tempName, String tableName) {  
          DbUtils.joinColumns(db, tempName, tableName);  
        }  

    }  

        final class DbUtils {  
    
            private static final String TAG = "DbUtils";  
            private static final boolean DEBUG = false;  
    
            private static final String SQLITE_STMT_LIST_TABLES =  
                "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE 'android%'";  
            private static final String SQLITE_TABLE_NAME_COLUMN = "name";  
            private static final String SQLITE_STMT_TEMPLATE_LIST_COLUMNS = "SELECT * FROM %s LIMIT 1";  
            private static final String SQLITE_STMT_TEMPLATE_DROP_TABLE = "DROP TABLE IF EXISTS %s";  
            private static final String SQLITE_STMT_TEMPLATE_RENAME_TABLE = "ALTER TABLE %s RENAME TO %s";  
            private static final String SQLITE_STMT_TEMPLATE_COPY_COLUMNS = "INSERT INTO %s (%s) SELECT %s FROM %s";  
    
    
            /** 
             * @param db 
             * @return Collection object containing table names in the database  
             */  
            static Collection<String> listTables(SQLiteDatabase db) {  
    
                Cursor cursor = db.rawQuery(SQLITE_STMT_LIST_TABLES, null);  
                if (cursor == null || !cursor.moveToFirst()) {  
    
                    if (cursor != null) {  
                        cursor.close();  
                    }  
                    return null;  
                }  
    
                int table_name_column = cursor.getColumnIndex(SQLITE_TABLE_NAME_COLUMN);  
                HashSet<String> tables = new HashSet<String>(cursor.getCount());  
                do {  
                    tables.add(cursor.getString(table_name_column));  
                } while (cursor.moveToNext());  
                cursor.close();  
    
    
                return tables;  
            }  
    
    
            /** 
             * @param db 
             * @param table 
             * @return List of column names in the DB table 
             */  
            public static List<String> listColumns(SQLiteDatabase db, String table) {  
    
                Cursor cursor = db.rawQuery(String.format(SQLITE_STMT_TEMPLATE_LIST_COLUMNS, table), null);  
                if (cursor == null) {  
                    return null;  
                }  
    
                List<String> columns = Arrays.asList(cursor.getColumnNames());  
                cursor.close();  
    
                return columns;  
            }  
    
    
            /** 
             * @param db 
             * @param table 
             */  
            static void dropTable(SQLiteDatabase db, String table) {  
    
                db.execSQL(String.format(SQLITE_STMT_TEMPLATE_DROP_TABLE, table));  
            }  
    
    
            static void renameTable(SQLiteDatabase db, String oldName, String newName) {  
    
                db.execSQL(String.format(SQLITE_STMT_TEMPLATE_RENAME_TABLE, oldName, newName));  
            }  
    
    
            static void joinColumns(SQLiteDatabase db, String oldTable, String newTable) {  
    
                //Delete all records in the new table before copying from the old table  
                db.delete(newTable, null, null);  
    
                //Find columns which exist in both tables  
                ArrayList<String> old_columns = new ArrayList<String>(listColumns(db, oldTable));  
                List<String> new_columns = listColumns(db, newTable);  
                old_columns.retainAll(new_columns);  
    
                String common_columns = TextUtils.join(",", old_columns);  
    
                //Copy records from old table to new table  example:         INSERT INTO Mytest1 (_id,account_id,test1,test3) SELECT _id,account_id,test1,test3 FROM Mytest1_temp_ 
                db.execSQL(String.format(SQLITE_STMT_TEMPLATE_COPY_COLUMNS, newTable, common_columns, common_columns, oldTable));  
            }  
    
        }  

    然后在DBHelper中重載onUpgrade方法:
        @Override  
           public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
    
               //Get table names in the old DB  
               Collection<String> old_tables = DbUtils.listTables(db);  
               if (old_tables == null || old_tables.size() == 0) {  
                   onCreate(db);  
                   return;  
               }  
    
               //Get table names in the new DB  
               Set<String> new_tables = DataBaseClass.sRCMDbTables.keySet();  
    
               try {  
                   db.beginTransaction();  
                   //Remove old tables which are not in the new DB scheme  
                   HashSet<String> obsolete_tables = new HashSet<String>();  
                   for (String table : old_tables) {  
                       if (!new_tables.contains(table)) {  
                        System.out.println("====DBHelp onUpgrade droptable table="+table);  
                           DbUtils.dropTable(db, table);  
                           obsolete_tables.add(table);  
                       }  
                   }  
                   old_tables.removeAll(obsolete_tables);  
    
                   //Create and upgrade new tables   
                   DbBaseTable table_descriptor;   
                   for (String table : new_tables) {  
                       table_descriptor = DataBaseClass.sRCMDbTables.get(table);  
    
                       //Check if the new table exists in the old DB  
                       if (old_tables.contains(table)) {  
                           String temp_name = getTempTableName(table, old_tables, new_tables);  
                           System.out.println("====DBHelp onUpgrade temp_name ="+temp_name);  
                           table_descriptor.onUpgrade(db, oldVersion, newVersion, temp_name);  
                       } else {  
                           table_descriptor.onCreate(db);  
                       }  
                   }  
                   db.setTransactionSuccessful();  
               } catch (Throwable e) {  
    
                   throw new RuntimeException("DB upgrade failed: " + e.getMessage());  
               } finally {  
                   db.endTransaction();  
               }  
           }  


    中心思想是:

    對比新舊的database結構,如果舊表中有table新的database里沒有,則刪除舊表里的

    如果新database中有一個table更新,則需要更新這個表的結構,然后把舊表中數據拷貝過來

    (把舊表rename一個名字,把命名后的表中的數據拷貝到新表中)

     本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!