【问题标题】:How do I import an existing SQLite3 database into Room?如何将现有的 SQLite3 数据库导入 Room?
【发布时间】:2018-12-09 04:01:00
【问题描述】:

好的,所以我在桌面上使用 SQLite3 创建了一个只需要读取的某些信息的数据库。我正在制作的应用程序不需要在此表中插入或删除信息。

我在 Room 数据库层上进行了相当多的谷歌搜索,所有文档都需要在构建您的应用程序时在 Room 中创建一个新的数据库——这是我不想要的,因为我已经有了一个。

我将如何让 Room 读取已经存在的数据库?我的数据库目前存储在/app/src/main/assets/splitbilldatabase.db

【问题讨论】:

    标签: java android sqlite android-room


    【解决方案1】:

    如果您使用的是 Room 2.2.0 或更高版本,您可以将数据库构建器配置为首先从 assets 文件夹加载数据库。

    Room.databaseBuilder(appContext, AppDatabase.class, "splitbilldatabase.db")
        .createFromAsset("splitbilldatabase.db")
        .build()
    

    更多信息: - https://developer.android.com/training/data-storage/room/prepopulate

    【讨论】:

      【解决方案2】:

      您需要做的第一件事是为 Room 架构创建所有内容以供导入(@Database、@Entity 用于表等),这些架构必须完全匹配数据库的架构被导入。

      应将外部数据库文件(与您一样)复制到 assets 文件夹。

      然后,您基本上可以在尝试打开 Room 数据库之前复制文件,例如在RoomDatabase init 方法中,但仅当文件/数据库不存在时

      以下是一个有效(但未经广泛测试)的示例:-

      @Database(entities = {MyTable.class,
              MyOthertable.class,
              MyMappingTable.class},version = 1,
              exportSchema = false)
      
      public abstract class  MyDatabase extends RoomDatabase {
      
          public static final String DBNAME = "splitbilldatabase.db";
      
      
          public static final String TB_MYTABLE = "mytable";
          public static final String TB_MYOTHERTABLE = "myothertable";
          public static final String TB_MYMAPPINGTABLE = "mymappingtable";
      
          public static final String COL_MYTABLE_ID = BaseColumns._ID;
          public static final String COL_MYTABLE_NAME = "_name";
          public static final String COL_MYTABLE_DESCRIPTION = "_description";
      
          public static final String COL_MYOTHERTABLE_ID = BaseColumns._ID;
          public static final String COL_MYOTHERTABLE_OTHERDETAILS = "_otherdetails";
      
          public static  final String COL_MYMAPPINGTABLE_MYTABLEREFERENCE = "_mytable_reference";
          public static final String COL_MYMAPPINGTABLE_MYOTEHERTABLEREFERENCE = "_myothertable_reference";
      
          public abstract MyTableDao myTableDao();
          public abstract MyOtherTableDao myOtherTableDao();
          public abstract MyMappingTableDao myMappingTableDao();
      
          public MyDatabase() {
              super();
          }
      
          @Override
          public void init(@NonNull DatabaseConfiguration configuration) {
              importExistingDatabase(configuration.context, true); //<<<<<<<<<< Invokes the Import of the Exisiting Database.
              super.init(configuration);
          }
      
          private void importExistingDatabase(Context context, boolean throw_exception) {
              int buffer_size = 32768;
              File dbpath = context.getDatabasePath(DBNAME);
              if (dbpath.exists()) {
                  return; // Database already exists
              }
              // Just in case make the directories
              File dirs = new File(dbpath.getParent());
              dirs.mkdirs();
              int stage = 0;
              byte[] buffer = new byte[buffer_size];
              long total_bytes_read = 0;
              long total_bytes_written = 0;
              int bytes_read = 0;
              try {  
                  InputStream assetdb = context.getAssets().open(DBNAME);
                  stage++;
                  dbpath.createNewFile();
                  stage++;
                  OutputStream realdb = new FileOutputStream(dbpath);
                  stage++;
                  while((bytes_read = assetdb.read(buffer)) > 0) {
                      total_bytes_read = total_bytes_read + bytes_read;
                      realdb.write(buffer,0,bytes_read);
                      total_bytes_written = total_bytes_written + bytes_read;
                  }
                  stage++;
                  realdb.flush();
                  stage++;
                  assetdb.close();
                  stage++;
                  realdb.close();
                  stage++;
              } catch (IOException e) {
                  String failed_at = "";
                  switch  (stage) {
                      case 0:
                          failed_at = "Opening Asset " + DBNAME;
                          break;
                      case 1:
                          failed_at = "Creating Output Database " + dbpath.getAbsolutePath();
                          break;
                      case 2:
                          failed_at = "Genreating Database OutputStream " + dbpath.getAbsolutePath();
                          break;
                      case 3:
                          failed_at = "Copying Data from Asset Database to Output Database. " +
                                  " Bytes read=" + String.valueOf(total_bytes_read) +
                                  " Bytes written=" + String.valueOf(total_bytes_written);
                          break;
                      case 4:
                          failed_at = "Flushing Written Data (" +
                                  String.valueOf(total_bytes_written) +
                                  " bytes written)";
                          break;
                      case 5:
                          failed_at = "Closing Asset Database File.";
                          break;
                      case 6:
                          failed_at = "Closing Created Database File.";
                  }
                  String msg = "An error was encountered copying the Database " +
                          "from the asset file to New Database. " +
                          "The error was encountered whilst :-\n\t" + failed_at;
                  Log.e("IMPORTDATABASE",msg);
                  e.printStackTrace();
                  if (throw_exception) {
                      throw new RuntimeException(msg);
                  }
              }
          }
      }
      
      • 请注意,假设文件名相同。

      【讨论】:

      • 所以我不需要在数据库中添加任何额外的东西让Android喜欢它?
      • @SikuM 我不这么认为。额外的表(1 个用于存储区域设置的房间和 android_metadata 将由底层代码创建)
      猜你喜欢
      • 2019-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 2010-09-23
      • 2020-01-13
      相关资源
      最近更新 更多