2010-11-20 26 views
18

Ứng dụng của tôi sử dụng hai cơ sở dữ liệu (các tệp riêng biệt). Để xử lý các cơ sở dữ liệu này, tôi đã tạo ra hai lớp Helper mở rộng SQLiteOpenHelper, một cho mỗi cơ sở dữ liệu. Bây giờ tôi sẽ thêm một cơ sở dữ liệu thứ ba và tự hỏi liệu tôi có cần tạo một lớp Helper khác không (và nếu tôi sử dụng cơ sở dữ liệu thứ 4 và thứ 5 thì tôi sẽ cần nhiều lớp trợ giúp hơn), hoặc tôi có thể sử dụng cùng một cơ sở dữ liệu Lớp trình trợ giúp cho nhiều cơ sở dữ liệu?Android: tôi có thể sử dụng một lớp SQLiteOpenHelper cho nhiều tệp cơ sở dữ liệu không?

Sự cố mà tôi thấy khi cố sử dụng chỉ một lớp Trình trợ giúp là tôi không thể xem cách chuyển tên của tệp cơ sở dữ liệu riêng lẻ cho Trình trợ giúp. Hiện tại tên của cơ sở dữ liệu được mã hóa cứng như một trường tĩnh của mỗi lớp của trình trợ giúp, nhưng nếu tôi chỉ có một lớp trình trợ giúp, tôi sẽ cần có khả năng truyền các tên khác nhau cho Constructor khi tạo trình trợ giúp riêng biệt các đối tượng; vấn đề là SQLiteOpenHelper Constructor dường như được gọi bởi Android chỉ với một tham số: Ngữ cảnh.

+0

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

Trả lời

16

Tất nhiên, bạn có thể. Nó chỉ là vấn đề của thiết kế lớp Helper của bạn. Bạn chỉ có thể chuyển tên DB cho hàm tạo lớp Trợ giúp của bạn (cùng với yêu cầu Context ví dụ) thay vì mã hóa cứng:

public class DBOpenHelper extends SQLiteOpenHelper { 

    public DBOpenHelper(Context context, String dbName, int dbVersion) { 
     super(context, dbName, null, dbVersion); 
    } 
... 
} 
+0

Silly me! Tôi đã không đọc mã tạo mã đối tượng Helper của tôi một cách chính xác. Như bạn nói, nó rất đơn giản. – prepbgg

+0

Xin chào, tôi muốn đặt một câu hỏi (hy vọng nó không quá đơn giản/rõ ràng), đó là cách bạn lặp qua lớp trợ giúp để tạo ra tất cả các cơ sở dữ liệu? Bạn đã lặp qua lớp trợ giúp bằng cách sử dụng vòng lặp for cho số lượng cơ sở dữ liệu bạn muốn tạo và chuyển vào tất cả các tên cơ sở dữ liệu? – jamen

2

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(); 
} 
+0

Tôi e rằng điều này quá phức tạp đối với tôi! Có lẽ tôi nên gắn bó với nhiều lớp trợ giúp cho nhiều cơ sở dữ liệu. – prepbgg

+0

Bạn có tất cả các đoạn mã phức tạp ở đó. Bạn chỉ cần quấn trong một chu kỳ và quấn các công cụ giao dịch xung quanh. Có những thứ phức tạp hơn thế này. – Pentium10

Các vấn đề liên quan