Android 資料庫升級解決方案

來源:互聯網
上載者:User

標籤:

請考慮如下情況:

在資料庫升級時,不同版本的資料庫,他們定義的表結構完全可能是不一樣的,比如V1.0的表A有10個column,而在V1.1的表A有12個colum,在升級時,表A增加了兩列,此時我們應該怎麼做呢。

 

總體思路

 

1,將表A重新命名,改了A_temp。

2,建立新表A。

3,將表A_temp的資料插入到表A。

下面代碼列出了更新表的實現,upgradeTables,給定表名,更新的列名,就可以實現資料庫表的更新。

 

[java] view plain copy
  1. /** 
  2.  * Upgrade tables. In this method, the sequence is: 
  3.  * <b> 
  4.  * <p>[1] Rename the specified table as a temporary table. 
  5.  * <p>[2] Create a new table which name is the specified name. 
  6.  * <p>[3] Insert data into the new created table, data from the temporary table. 
  7.  * <p>[4] Drop the temporary table. 
  8.  * </b> 
  9.  * 
  10.  * @param db The database. 
  11.  * @param tableName The table name. 
  12.  * @param columns The columns range, format is "ColA, ColB, ColC, ... ColN"; 
  13.  */  
  14. protected void upgradeTables(SQLiteDatabase db, String tableName, String columns)  
  15. {  
  16.     try  
  17.     {  
  18.         db.beginTransaction();  
  19.   
  20.         // 1, Rename table.  
  21.         String tempTableName = tableName + "_temp";  
  22.         String sql = "ALTER TABLE " + tableName +" RENAME TO " + tempTableName;  
  23.         execSQL(db, sql, null);  
  24.   
  25.         // 2, Create table.  
  26.         onCreateTable(db);  
  27.   
  28.         // 3, Load data  
  29.         sql =   "INSERT INTO " + tableName +  
  30.                 " (" + columns + ") " +  
  31.                 " SELECT " + columns + " FROM " + tempTableName;  
  32.   
  33.         execSQL(db, sql, null);  
  34.   
  35.         // 4, Drop the temporary table.  
  36.         execSQL(db, "DROP TABLE IF EXISTS " + tempTableName, null);  
  37.   
  38.         db.setTransactionSuccessful();  
  39.     }  
  40.     catch (SQLException e)  
  41.     {  
  42.         e.printStackTrace();  
  43.     }  
  44.     catch (Exception e)  
  45.     {  
  46.         e.printStackTrace();  
  47.     }  
  48.     finally  
  49.     {  
  50.         db.endTransaction();  
  51.     }  
  52. }  

 

得到資料庫表的列名

 

我們可以通過SQL表得到表的列名。 這裡需要注意的一點,int columnIndex = c.getColumnIndex("name"); 這雷根據name去取得index。 

[java] view plain copy
  1. protected String[] getColumnNames(SQLiteDatabase db, String tableName)  
  2. {  
  3.     String[] columnNames = null;  
  4.     Cursor c = null;  
  5.   
  6.     try  
  7.     {  
  8.         c = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);  
  9.         if (null != c)  
  10.         {  
  11.             int columnIndex = c.getColumnIndex("name");  
  12.             if (-1 == columnIndex)  
  13.             {  
  14.                 return null;  
  15.             }  
  16.   
  17.             int index = 0;  
  18.             columnNames = new String[c.getCount()];  
  19.             for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext())  
  20.             {  
  21.                 columnNames[index] = c.getString(columnIndex);  
  22.                 index++;  
  23.             }  
  24.         }  
  25.     }  
  26.     catch (Exception e)  
  27.     {  
  28.         e.printStackTrace();  
  29.     }  
  30.     finally  
  31.     {  
  32.         closeCursor(c);  
  33.     }  
  34.   
  35.     return columnNames;  
  36. }  

 

upgradeTables方法應該是在onUpgrade方法中去調用。

 

資料庫升級的意義

 

 

在應用程式開發的過程中,資料庫的升級是一個很重要的組成部分(如果用到了資料庫),因為程式可能會有V1.0,V2.0,當使用者安裝新版本的程式 後,必須要保證使用者資料不能丟失,對於資料庫設計,如果發生變更(如多添加一張表,表的欄位增加或減少等),那麼我們必須想好資料庫的更新策略。

1,定義資料庫版本

 

資料庫的版本是一個整型值,在建立SQLiteOpenHelper時,會傳入該資料庫的版本,如果傳入的資料庫版本號碼比資料庫檔案中儲存的版本號碼大的話,那麼SQLiteOpenHelper#onUpgrade()方法就會被調用,我們的升級應該在該方法中完成。

2,如何寫升級邏輯

 

假如我們開發的程式已經發布了兩個版本:V1.0,V1.2,我們正在開發V1.3。每一版的資料庫版本號碼分別是18,19,20。

對於這種情況,我們應該如何?升級?

使用者的選擇有:                   

1) V1.0 -> V1.3  DB 18 -> 20                  

2) V1.1 -> V1.3  DB 19 -> 20      

3,注意

資料庫的每一個版本所代表的資料庫必須是定義好的,比如說V18的資料庫,它可能只有兩張表TableA和TableB,如果V19要添加一張表TableC,如果V20要修改TableC,那麼每一個版本所對應的資料庫結構如下:

V18  --->  TableA, TableB

V19  --->  TableA, TableB, TableC

V20  --->  TableA, TableB, TableC (變更)

onUpgrade()方法的實現如下:

 

[java] view plain copy
  1.        // Pattern for upgrade blocks:  
  2. //  
  3. //    if (upgradeVersion == [the DATABASE_VERSION you set] - 1){  
  4. //        .. your upgrade logic..  
  5. //        upgradeVersion = [the DATABASE_VERSION you set]  
  6. //    }  
  7.   
  8.   
  9. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)  
  10. {  
  11.     int upgradeVersion  = oldVersion;  
  12.   
  13.     if (18 == upgradeVersion) {  
  14.         // Create table C  
  15.         String sql = "CREATE TABLE ...";  
  16.         db.execSQL(sql);  
  17.         upgradeVersion = 19;  
  18.     }  
  19.   
  20.     if (20 == upgradeVersion) {  
  21.         // Modify table C  
  22.         upgradeVersion = 20;  
  23.     }  
  24.   
  25.     if (upgradeVersion != newVersion) {  
  26.         // Drop tables  
  27.         db.execSQL("DROP TABLE IF EXISTS " + tableName);  
  28.         // Create tables  
  29.         onCreate(db);  
  30.     }  
  31. }  

從上面的代碼可以看到,我們在onUpgrade()方法中,處理了資料庫版本從18 -> 20的升級過程,這樣做的話,不論使用者從18 -> 20,還是從19 -> 20,最終程式的資料庫都能升級到V20所對應的資料庫結構。  

 

4,如何保證資料不丟失

 

這是很重要的一部分,假設要更新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;                

                   
經過這三步,TableC就完成了更新,同時,也保留了原來表中的資料。  

注意:

在onUpgrade()方法中,刪除表時,注意使用交易處理,使得修改能立即反應到資料庫檔案中。       

SQL語句

 

由於Android是使用開源的SQLite3作為其資料庫,所以,我們在開發資料庫模組時,一定要注意SQLite3支援哪些關鍵字,函數等,不是所有的關鍵字,SQLite都是支援的。

下面列出了一些參考連結:

SQLite3官方文檔:http://sqlite.org/

W3CSchool網站:http://www.w3school.com.cn/sql/index.asp/

SQL語句寫得好壞能直接影響到資料庫的操作。我曾經就遇到過SQL語句影響查詢效能,更新3000條記錄,用時30移左右,但在對WHERE條件的欄位加上索引後,效能提升到3~4秒。

Android 資料庫升級解決方案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.