2009-12-23 39 views
6

Cơ sở dữ liệu của ứng dụng của tôi cần phải được lấp đầy nhiều dữ liệu, vì vậy trong thời gian onCreate(), nó không chỉ tạo ra một số bảng sql hướng dẫn, có rất nhiều chèn. Giải pháp tôi chọn là để lưu trữ tất cả các hướng dẫn này trong một tệp sql nằm trong res/raw và được tải với Resources.openRawResource(id).Tạo cơ sở dữ liệu ứng dụng android với số lượng lớn dữ liệu

Nó hoạt động tốt nhưng tôi phải đối mặt với vấn đề mã hóa, tôi có một số dấu ngoặc kép nổi bật trong tệp sql xuất hiện không tốt trong đơn đăng ký của tôi. mã của tôi này để làm điều này:

public String getFileContent(Resources resources, int rawId) throws 
IOException 
    { 
    InputStream is = resources.openRawResource(rawId); 
    int size = is.available(); 
    // Read the entire asset into a local byte buffer. 
    byte[] buffer = new byte[size]; 
    is.read(buffer); 
    is.close(); 
    // Convert the buffer into a string. 
    return new String(buffer); 
    } 

public void onCreate(SQLiteDatabase db) { 
    try { 
     // get file content 
     String sqlCode = getFileContent(mCtx.getResources(), R.raw.db_create); 
     // execute code 
     for (String sqlStatements : sqlCode.split(";")) 
     { 
      db.execSQL(sqlStatements); 
     } 

     Log.v("Creating database done."); 
     } catch (IOException e) { 
      // Should never happen! 
      Log.e("Error reading sql file " + e.getMessage(), e); 
      throw new RuntimeException(e); 
     } catch (SQLException e) { 
      Log.e("Error executing sql code " + e.getMessage(), e); 
      throw new RuntimeException(e); 
     } 

Giải pháp tôi thấy để tránh điều này là để tải các hướng dẫn sql từ một khổng lồ static final String thay vì một tập tin, và tất cả nhân vật nổi bật xuất hiện tốt.

Nhưng không có cách nào thanh lịch hơn để tải hướng dẫn sql hơn một thuộc tính lớn static final String với tất cả hướng dẫn sql?

Trả lời

8

Tôi nghĩ vấn đề của bạn là ở dòng này:

return new String(buffer); 

Bạn đang chuyển đổi mảng byte vào một java.lang.String nhưng bạn không nói với Java/Android mã hóa để sử dụng. Vì vậy, các byte cho các ký tự có dấu của bạn không được chuyển đổi chính xác vì mã hóa sai đang được sử dụng.

Nếu bạn sử dụng constructor String(byte[],<encoding>) bạn có thể chỉ định mã hóa tập tin của bạn đã, đang và nhân vật của bạn sẽ được chuyển đổi một cách chính xác.

+0

Cảm ơn rất nhiều Dave – tbruyelle

4

Các tập tin SQL giải pháp dường như hoàn hảo, nó chỉ là những gì bạn cần để đảm bảo rằng các tập tin được lưu trong bảng mã utf8 nếu không tất cả các nhân vật nổi bật sẽ bị mất. Nếu bạn không muốn thay đổi mã hóa của tệp, bạn cần phải chuyển đối số thừa sang số String(bytes, charset) mới xác định mã hóa của tệp.

Đừng thích sử dụng các nguồn lực tập tin thay vì chuỗi thức tĩnh để tránh phải tất cả những byte không cần thiết nạp vào bộ nhớ. Trong điện thoại di động bạn muốn lưu tất cả bộ nhớ có thể!

-1

Dường như bạn đang chuyển tất cả các câu lệnh sql của bạn trong một chuỗi. Đó là một vấn đề bởi vì execSQL mong đợi "một câu lệnh không phải là một truy vấn" (xem tài liệu [ở đây] [1]). Sau đây là một giải pháp hơi xấu xí nhưng làm việc.

tôi có tất cả các câu sql của tôi trong một tập tin như thế này:

INSERT INTO GIÁ TRỊ table1 (1, 2, 3);

INSERT INTO GIÁ TRỊ table1 (4, 5, 6);

INSERT INTO table1 VALUES (7, 8, 9);

Thông báo các dòng mới ở giữa văn bản (dấu chấm phẩy sau đó là 2 dòng mới) Sau đó, tôi làm điều này:

String text = new String(buffer, "UTF-8"); 
for (String command : text.split(";\n\n")) { 
    try { command = command.trim(); 
    //Log.d(TAG, "command: " + command); 
    if (command.length() > 0) 
     db.execSQL(command.trim()); 
} 
catch(Exception e) {do whatever you need here} 

cột dữ liệu của tôi chứa các đốm màu của text với các dòng mới và dấu chấm phẩy, vì vậy tôi phải tìm một dấu phân cách lệnh khác.Chỉ cần chắc chắn để có được sáng tạo với phân chia str: sử dụng một cái gì đó bạn biết không tồn tại trong dữ liệu của bạn.

HTH Gerardo

[1]: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String, java.lang.Object [])

+0

Tôi cũng chia nhỏ (";") và vấn đề của tôi không phải về các câu lệnh sql mà là mã hóa ký tự. – tbruyelle

1

Tôi đang sử dụng một cách tiếp cận khác nhau: Thay vì thực hiện tải các câu lệnh SQL (mà sẽ mất thời gian dài để hoàn thành), tôi xây dựng cơ sở dữ liệu sqlite của mình trên màn hình nền, đặt nó vào thư mục asset, tạo một sqlite db trống trong android và sao chép db từ thư mục asset vào thư mục cơ sở dữ liệu. Đây là một sự gia tăng rất lớn về tốc độ. Lưu ý, bạn cần phải tạo một cơ sở dữ liệu trống đầu tiên trong Android, và sau đó bạn có thể sao chép và ghi đè lên nó. Nếu không, Android sẽ không cho phép bạn viết một db vào thư mục datbase. Có một số ví dụ trên internet. BTW, có vẻ cách tiếp cận này hoạt động tốt nhất, nếu db không có phần mở rộng tệp.

+0

bạn có thể chia sẻ mã bạn đã sử dụng không? –

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