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下载

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

时间: 2024-10-01 05:10:13

android数据库升级的措辞的相关文章

Android 数据库升级完整解决方案

数据库升级的意义 我们在开发Android应用的时候,不可避免地要使用数据库.而数据库的结构在第一版的时候定下来,之后发布功能更新,或增加业务逻辑,原来的数据库结构可能就不适用了.而如果数据库的结构与之前版本的结构不同,新版本的应用读取旧数据库肯定会出问题.解决办法只有两种: 1.让用户卸载老版本再安装新的程序: 2.软件自行更新数据库结构. 第一种办法很明显不具备可操作性,而且用户一旦卸载软件,数据就丢失了,这是不能容忍的事情.因此,作为开发者必须妥善处理数据库的升级问题. 当然了,有的同学会

优雅的处理Android数据库升级的问题

原始完成于:2015-04-27 19:28:22 提供一种思路,优雅的处理Android数据库升级的问题,直接上代码: 1 package com.example.databaseissuetest; 2 3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteOpenHelper; 6 import and

Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())

数据库版本升级对软件的管理操作. 我们手机经常会收到xxx软件升级什么的提醒,你的软件版本更新,同时你的数据库对应的版本也要相应的更新. 数据库版本更新需要主要的问题: 软件的1.0版本升级到1.1版本时,老的数据不能丢. 那么在1.1版本的程序中就要有地方能够检测出来新的软件版本与老的数据库不兼容,并且能够有办法把1.0软件的数据库升级到1.1软件能够使用的数据库. 换句话说,要在1.0软件的数据库的那个表中增加那个字段,并赋予这个字段默认值. 当然有的时候我们对更新后的 版本并没有什么好感,

Android 数据库升级解决方案

转自:http://blog.csdn.net/leehong2005/article/details/9128501 请考虑如下情况: 在数据库升级时,不同版本的数据库,他们定义的表结构完全可能是不一样的,比如V1.0的表A有10个column,而在V1.1的表A有12个colum,在升级时,表A增加了两列,此时我们应该怎么做呢. 总体思路 1,将表A重命名,改了A_temp. 2,创建新表A. 3,将表A_temp的数据插入到表A. 下面代码列出了更新表的实现,upgradeTables,给

Android数据库升级实例

第一部分 Andoird的SQLiteOpenHelper类中有一个onUpgrade方法.帮助文档中只是说当数据库升级时该方法被触发.经过实践,解决了我一连串的疑问: 1. 帮助文档里说的“数据库升级”是指什么? 你开发了一个程序,当前是1.0版本.该程序用到了数据库.到1.1版本时,你在数据库的某个表中增加了一个字段.那么软件1.0版本用的数据库在软件1.1版本就要被升级了. 2. 数据库升级应该注意什么? 软件的1.0版本升级到1.1版本时,老的数据不能丢.那么在1.1版本的程序中就要有地

Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())的注意点

以下内容可以作为面试官在面试的时候的问题,感觉比较好,是比较常用的知识点,可以用来考察基础是否扎实. 也可以程序猿学习.开发中的注意点.因为稍微不注意,就有可能导致数据库不能用. DBAdapter.java是一个简单的类,主要用来进行数据库操作. 1 package com.example.test_20131218; 2 3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 6

Android 数据库升级

数据库升级:v1.0-v2.1从v1.0升级到v2.01,不走oncreate,走onupdategrade直接安装v2.0,走onCreate; v1.0-v3.0:分三种情况1.v1.0升级到v3.0: 不走onCreate,走onUpgrade2.v2.0升级到v3.0:不走onCreate,走onUpgrade3.直接安装v3.0:走onCreate,不走onUpgradepublic class DbHelper extends SQLiteOpenHelper { // privat

Android数据库升级,数据不丢失解决方案

假设要更新TableC表,建议的做法是: 1) 将TableC重命名为TableC_temp SQL语句可以这样写:ALERT TABLE TableC RENAME TO TableC_temp; 2) 创建新的TableC表 3) 将数据从TableC_temp中插入到TableC表中 SQL语句可以这样写:INSERT INTO TableC (Col1, Col2, Col3) SELECT (Col1, Col2, Col3) FROM TableC_temp; 经过这三步,Table

Android 数据库读取数据显示 [5]

2016-12-1 课程内容 昨天学了Android数据库升级.降级.创建 今天把数据库表里面的数据读取出来显示到手机屏幕上 下面代码是MainActivity.java 的代码 package com.example.winxinmff; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;