Android資料庫升級不丟失資料解決方案

lsc183發表於2015-04-23

  在Android開發中,sqlite至關重要,增刪查改不多說,難點在於,1,併發,多個執行緒同時運算元據庫。2,版本升級時,如果資料庫表中新加了個欄位,如何在不刪除表的情況下順利過渡,從而不丟失資料。

  資料庫操作建議用ORM框架,簡單高效。這裡推薦xUtils,裡面包含DBUtils。github地址:https://github.com/wyouflf/xUtils。關於DBUtils,它是這樣介紹的:

  • android中的orm框架,一行程式碼就可以進行增刪改查;
  • 支援事務,預設關閉;
  • 可通過註解自定義表名,列名,外來鍵,唯一性約束,NOT NULL約束,CHECK約束等(需要混淆的時候請註解表名和列名);
  • 支援繫結外來鍵,儲存實體時外來鍵關聯實體自動儲存或更新;
  • 自動載入外來鍵關聯實體,支援延時載入;
  • 支援鏈式表達查詢,更直觀的查詢語義,參考下面的介紹或sample中的例子。

     用單例方式獲取資料庫例項。

  static DbUtils db = null;

  public static DbUtils getDb(Context context) {

    if (context == null) {

      context = DoctorApplication.getInstance();

    }

    if (db == null) {

      db = DbUtils.create(context, "xUtils.db");

    });

    db.configAllowTransaction(true);

    return db;

  }

    db.configAllowTransaction(true);

    return db;

}

    db.configAllowTransaction(true); 標示開啟事務,這樣多個執行緒運算元據庫時就不會出現問題了。

   資料庫升級解決方案。首先建立一個實體類,對應資料庫中的表。

@Table(name = "User")

  public class User {

    private int id; //主鍵ID,必須

    private String uid;  

    private String type;

    public int getId() {

          return id;

      }

       public void setId(int id) {

            this.id = id;

      }

    public String getType() {

      return type;

    }  

    public void setType(String type) {

      this.type = type;

    }

    public String getUid() {

      return uid;

    }

    public void setUid(String uid) {

      this.uid = uid;

    } 

  }

 

  如果由版本1到版本2中,User表中新增了個欄位title,如何在不刪除表User的情況下順利過渡呢,我們知道,如果不作處理,資料庫就會報錯,沒有列title。我們修改資料庫的建立方式,實現升級介面。 

  

db = DbUtils.create(context, "xUtils.db", 3, new DbUpgradeListener() {

  @Override

  public void onUpgrade(DbUtils db, int oldVersion, int newVersion) {

    if (newVersion > oldVersion) {

      updateDb(db, "User");

    }

  }

  });

 

  updateDb方法中比較類的屬性和之前版本資料庫表中的欄位,如果屬性沒有對應到欄位,則新增相應的欄位。

private static void updateDb(DbUtils db, String tableName) {

try {

Class<EntityBase> c = (Class<EntityBase>) Class.forName("com.henizaiyiqi.doctorassistant.entitis." + tableName);// 把要使用的類載入到記憶體中,並且把有關這個類的所有資訊都存放到物件c中

if (db.tableIsExist(c)) {

List<String> dbFildsList = new ArrayList<String>();

String str = "select * from " + tableName;

Cursor cursor = db.execQuery(str);

int count = cursor.getColumnCount();

for (int i = 0; i < count; i++) {

dbFildsList.add(cursor.getColumnName(i));

}

cursor.close();

Field f[] = c.getDeclaredFields();// 把屬性的資訊提取出來,並且存放到field類的物件中,因為每個field的物件只能存放一個屬性的資訊所以要用陣列去接收

for (int i = 0; i < f.length; i++) {

String fildName = f[i].getName();

if (fildName.equals("serialVersionUID")) {

continue;

}

String fildType = f[i].getType().toString();

if (!isExist(dbFildsList, fildName)) {

if (fildType.equals("class java.lang.String")) {

db.execNonQuery("alter table " + tableName + " add " + fildName + " TEXT ");

} else if (fildType.equals("int") || fildType.equals("long") || fildType.equals("boolean")) {

db.execNonQuery("alter table " + tableName + " add " + fildName + " INTEGER ");

}

} 

}

}

} catch (Exception e) {

}

}

 

   這樣以後如果表中新增了欄位,只需把資料庫版本號加1,資料庫就會自動升級一次,就能保證資料正常了。

 

相關文章