Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android數據庫的升級的寫法

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 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 tables = new HashSet(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 listColumns(SQLiteDatabase db, String table) {
        
        Cursor cursor = db.rawQuery(String.format(SQLITE_STMT_TEMPLATE_LIST_COLUMNS, table), null);
        if (cursor == null) {
            return null;
        }
        
        List 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 old_columns = new ArrayList(listColumns(db, oldTable));
        List 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 old_tables = DbUtils.listTables(db);
        if (old_tables == null || old_tables.size() == 0) {
            onCreate(db);
            return;
        }
        
        //Get table names in the new DB
        Set new_tables = DataBaseClass.sRCMDbTables.keySet();
        
        try {
            db.beginTransaction();
            //Remove old tables which are not in the new DB scheme
            HashSet obsolete_tables = new HashSet();
            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一個名字,把命名後的表中的數據拷貝到新表中)

代碼可以在http://download.csdn.net/detail/baidu_nod/7684479下載

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved