Bạn cần một lớp trừu tượng triển khai quy trình nâng cấp được mô tả tại đây. Sau đó, bạn mở rộng lớp trừu tượng này cho mỗi bảng của bạn. Trong lớp trừu tượng của bạn, bạn phải lưu trữ các bảng theo cách (danh sách, mã hóa cứng) để khi onUpgrade kích hoạt bạn lặp qua các mục bảng và cho mỗi mục bảng bạn thực hiện các bước được mô tả. Họ sẽ được tự nâng cấp, giữ tất cả các chi tiết hiện có của họ. Xin lưu ý rằng sự kiện onUpgrade chỉ kích hoạt một lần cho mỗi cơ sở dữ liệu, đó là lý do tại sao bạn cần lặp lại tất cả các bảng của bạn để thực hiện nâng cấp tất cả chúng. Bạn chỉ duy trì 1 số phiên bản trên tất cả cơ sở dữ liệu.
- beginTransaction
- chạy một tạo bảng với
if not exists
(chúng tôi đang làm một bản nâng cấp, vì vậy các bảng có thể không tồn tại được nêu ra, nó sẽ thất bại thay đổi và thả)
- đặt trong một danh sách các cột hiện
List<String> columns = DBUtils.GetColumns(db, TableName);
- bảng sao lưu (
ALTER table " + TableName + " RENAME TO 'temp_" + TableName
)
- tạo bảng mới (schema tạo bảng mới nhất)
- được giao với các cột mới, cột thời gian này mất n từ bảng nâng cấp (
columns.retainAll(DBUtils.GetColumns(db, TableName));
)
- khôi phục dữ liệu (
String cols = StringUtils.join(columns, ","); db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TableName, cols, cols, TableName));
)
- bảng remove backup (
DROP table 'temp_" + TableName
)
- setTransactionSuccessful
(Điều này không xử lý bảng hạ cấp, nếu bạn đổi tên một cột , bạn không nhận được dữ liệu hiện có được chuyển vì tên cột không khớp).
.
public static List<String> GetColumns(SQLiteDatabase db, String tableName) {
List<String> ar = null;
Cursor c = null;
try {
c = db.rawQuery("select * from " + tableName + " limit 1", null);
if (c != null) {
ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
}
} catch (Exception e) {
Log.v(tableName, e.getMessage(), e);
e.printStackTrace();
} finally {
if (c != null)
c.close();
}
return ar;
}
public static String join(List<String> list, String delim) {
StringBuilder buf = new StringBuilder();
int num = list.size();
for (int i = 0; i < num; i++) {
if (i != 0)
buf.append(delim);
buf.append((String) list.get(i));
}
return buf.toString();
}
Hey man! Tôi đang làm một cái gì đó rất giống với u, nhưng trong trường hợp của tôi, tôi cần 2 lớp dbHelper khác nhau. Thing là tôi đang nhận được một lỗi trong khi cố gắng để làm như vậy. java.lang.IllegalStateException: Lớp trình trợ giúp là lớp X nhưng đang cố gắng đặt lại về lớp Y. bạn có từng gặp vấn đề này không? – Ajay