代码之家  ›  专栏  ›  技术社区  ›  tbruyelle

创建具有大量数据的android应用程序数据库

  •  6
  • tbruyelle  · 技术社区  · 16 年前

    我的应用程序数据库需要填充大量数据, 所以在 onCreate() 说明,有很多插页。我选择的解决办法是 将所有这些指令存储在res/raw中的sql文件中,并且 Resources.openRawResource(id) .

    它工作得很好,但我面对的编码问题,我有一些强调

    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);
            }
    

    我发现避免这种情况的解决方案是加载sql指令 从一个巨大的 static final String 而不是一个文件,以及所有 突出的字符看起来很好。

    静态最终字符串 属性是否包含所有sql指令?

    4 回复  |  直到 14 年前
        1
  •  8
  •   David Webb    16 年前

    我认为你的问题在于:

    return new String(buffer);
    

    java.lang.String 但您并没有告诉Java/Android要使用的编码。因此,由于使用了错误的编码,重音字符的字节没有正确转换。

    如果你使用 String(byte[],<encoding>)

        2
  •  4
  •   rui    16 年前

    SQL文件解决方案似乎很完美,只是您需要确保文件以utf8编码保存,否则所有重音字符都将丢失。如果不想更改文件的编码,则需要向new传递一个额外的参数 String(bytes, charset) 定义文件的编码。

        3
  •  1
  •   mrd    14 年前

    我正在使用一种不同的方法: 我在桌面上构建sqlite数据库,将其放在assets文件夹中,在android中创建一个空的sqlite db,并将db从assets文件夹复制到database文件夹中,而不是执行sql语句的加载(这需要很长时间才能完成)。这是速度上的巨大提升。注意,您需要先在android中创建一个空数据库,然后才能复制和覆盖它。否则,Android将不允许您将db写入datbase文件夹。互联网上有几个例子。 顺便说一句,如果db没有文件扩展名,这种方法似乎效果最好。

        4
  •  -1
  •   llappall    16 年前

    看起来您正在一个字符串中传递所有sql语句。这是一个问题,因为execSQL需要“一条不是查询的语句”(参见文档[here][1])。下面是一个有点难看但有效的解决方案。

    我将所有sql语句保存在如下文件中:

    在表1中插入数值(1、2、3);

    在表1中插入数值(4、5、6);

    请注意文本之间的新行(分号后跟两行新行) 然后,我这样做:

    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}
    

    我的数据列包含带有新行和分号的文本块,因此我必须找到不同的命令分隔符。只要确保使用splitstr时具有创造性:使用您知道数据中不存在的东西。

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