如何将现有的SQLite3数据库导入Room?

时间:2018-06-29 23:32:59

标签: java android sqlite android-room

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

我已经在Room数据库层上进行了一些Google搜索,并且所有文档都要求在构建应用程序时在Room中创建一个新的数据库,这是我不想要的,因为我已经拥有一个数据库。

我应该如何让Room读取一个已经存在的数据库?我的数据库当前存储在/app/src/main/assets/splitbilldatabase.db中。

2 个答案:

答案 0 :(得分:2)

如果使用的是Room 2.2.0或更高版本,则可以将数据库构建器配置为从资产文件夹中加载数据库开始。

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

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

答案 1 :(得分:1)

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

应该将外部数据库文件(如您所愿)复制到资产文件夹。

然后,您基本上可以先复制文件,然后再尝试打开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);
            }
        }
    }
}
  • 请注意,假设文件名相同。