zoukankan      html  css  js  c++  java
  • 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
    	<strong>DbUtils.renameTable(db, getName(), tempName);</strong>
    		
            //Create clear table according to the new scheme
           <strong> onCreate(db);</strong>
            //Copy content of the matching columns from the old table to the new one
           <strong> joinColumns(db, tempName, getName());</strong>
            
            //Delete old table
           <strong> DbUtils.dropTable(db, tempName);</strong>
            
            //这个是更新一些表的内容
            initTableContent(db);
        }
        
        void initTableContent(SQLiteDatabase db) {
        }
       
        void joinColumns(SQLiteDatabase db, String tempName, String tableName) {
        	<strong>DbUtils.joinColumns(db, tempName, tableName);</strong>
        }
    
    }
    

    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:<span style="font-family: 微软雅黑;"><strong><span style="font-size:10px;">INSERT INTO Mytest1 (_id,account_id,test1,test3) SELECT _id,account_id,test1,test3 FROM Mytest1_temp_</span></strong></span>
            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一个名字。把命名后的表中的数据复制到新表中)

    代码能够在http://download.csdn.net/detail/baidu_nod/7684479下载

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    使用react hook做一个小型完整项目(包括二级路由,动态路由,redux,tab切换,列表跳详情,登录, 守卫)
    项目实战【vue,react,微信小程序】(1705E)
    Vue(1706E)
    加入购物车动画(css)
    React从入门到精通(1704B)
    React(1702H)文章管理-cms系统
    React(1702H)文件上传和分页查找
    React (1702H) 点击复制、滚动条、图形验证码、ridis、密码rsa加密、token、发邮件、文件上传、sql语句
    位图算法
    def跨域+jwt
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4643169.html
Copyright © 2011-2022 走看看