在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,資料庫就會自動升級一次,就能保證資料正常了。