programing tip

미리 채워진 데이터베이스와 함께 Room Persistence Library를 사용하는 방법은 무엇입니까?

itbloger 2020. 12. 9. 07:55
반응형

미리 채워진 데이터베이스와 함께 Room Persistence Library를 사용하는 방법은 무엇입니까?


미리 채워진 데이터베이스로 Room을 사용하고 싶지만 Room에 내 데이터베이스를 찾을 수있는 위치를 알려주는 방법을 이해할 수 없습니다.

이제 그것을 src/main/assets/databases넣었고 Room 데이터베이스에 대한 인스턴스를 만들 때 다음과 같이 만듭니다.

Room.databaseBuilder(
    getApplicationContext(),
    AppDatabase.class,
    "justintrain.db"
)
.allowMainThreadQueries()
.build();

이런 식으로 매번 새로운 데이터베이스를 생성하거나 어쨌든 미리 채워진 데이터베이스를 사용하지 않는다고 생각합니다.

내 데이터베이스를 찾으려면 어떻게해야합니까?


이것이 제가 해결 한 방법이며, 미리 채워진 데이터베이스 (최대 Room v. alpha5)를 사용하여 애플리케이션을 제공하는 방법입니다.

  • SQLite DB database_name.dbassets/databases폴더에 넣으십시오.

  • 이 저장소 에서 파일 가져 와서 ie라는 패키지에 넣으십시오.sqlAsset

  • 당신의 AppDatabase클래스, 그에 따라 룸의 DB 생성 코드를 수정 :

    Room.databaseBuilder(context.getApplicationContext(), 
                         AppDatabase.class, 
                         "database_name.db")
    .openHelperFactory(new AssetSQLiteOpenHelperFactory())
    .allowMainThreadQueries()
    .build();
    

다른 방법 을 사용 "database_name.db"하지 않고 사용해야 getDatabasePath()합니다. 파일 이름 만 있으면됩니다.


다른 외부 라이브러리가없는 간단한 솔루션입니다.

Room은 기존 Android 프레임 워크 코드를 사용하여 데이터베이스를 만들거나 엽니 다. FrameworkSQLiteOpenHelper(Room 버전의 SQLiteOpenHelper) 소스 코드를 살펴보면 내부적으로 SQLiteOpenHelper.getReadableDatabase()필요한 곳마다 다른 메서드를 호출 합니다.

따라서 가장 간단한 해결책은 mContext.getDatabasePath("my-database.sqlite")Room으로 DB를 생성 하기 전에 assets 디렉터리에서 DB 파일을 복사하는 것 입니다.

귀하의 경우 코드는 다음과 같습니다.

private final String DB_NAME = "my-database.sqlite";

private MyDatabase buildDatabase(Context context) {
    final File dbFile = context.getDatabasePath(DB_NAME);

    if(!dbFile.exists()) {
        copyDatabaseFile(dbFile.getAbsolutePath());
    }

    return Room.databaseBuilder(context.getApplicationContext(),
        MyDatabase.class, DB_NAME)
        .build();
}

private void copyDatabaseFile(String destinationPath) {
    // code to copy the file from assets/database directory to destinationPath
}

이 링크에는 DB를 복사하는 데 필요한 코드가 있습니다.


나는 똑같은 문제를 겪고 있었기 때문에 정확히 그것을하는 라이브러리를 만들었습니다. 받아 들여지는 대답은 작동하지만 라이브러리를 사용하는 것이 더 쉽다고 생각합니다.

AppDatabase db = RoomAsset
    .databaseBuilder(context.getApplicationContext(), AppDatabase.class, "database_name.db")
    .build(); 

저장소 끝에있는 루트 build.gradle에 추가합니다.

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}

종속성 추가

dependencies {
    // ... other dependencies
    implementation 'com.github.humazed:RoomAsset:v1.0'
}

여기에서 라이브러리를 찾을 수 있습니다 : https://github.com/humazed/RoomAsset


해킹이나 종속성없이 작동하는 2019 솔루션 (Kotlin)

  1. 당신의 장소 .db에 파일을 assets/databases(한은 아래의대로가 나 정말 폴더 assets).

  2. Room 2.2의 기존 createFromAsset()함수를 사용하여 데이터베이스 경로를 전달합니다. 예를 들어, 데이터베이스 파일의 이름이 지정 my_data.db되고 폴더 databases디렉토리 아래에있는 assets경우 createFromAsset("databases/my_data.db").

데이터베이스 이름 (예 my_data:)이라는 상수 변수에 저장되어 있다고 가정하면 DATABASE_NAME다음 샘플 코드를 사용할 수 있습니다.

Room.databaseBuilder(
                    context.applicationContext,
                    MyDatabase::class.java,
                    DATABASE_NAME
                )
                    .createFromAsset("databases/$DATABASE_NAME.db")
                    .build()

Important: Make sure the schema of your data class/entity precisely matches the schema of your .db file. For example, if a column isn't explicitly marked as NOT NULL in the .db file, then that means the column can have null values in it. In Kotlin, you would have to match that with val colName: dataType? = null in your data class. If you just do val colName: dataType, Kotlin will compile that to a NOT NULL column, and that will throw an exception when you try to run your app.

Note: If instead you want to create a Room database from a database file that you download onto the Android device itself, you can alternatively use the createFromFile() function. Check out the official documentation on how to do this.


Similar solution with room without using external libraries: 1. Copy your database in assets folder 2. Copy your database from assets folder

public class MainActivity extends AppCompatActivity {

public static AppDatabase db;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    copyDatabase(getApplicationContext(), "yourdatabase.db");

    db = Room.databaseBuilder(getApplicationContext(), .class, "yourdatabase.db").allowMainThreadQueries().build();
}

private void copyDatabase(Context context, String databaseName) {
    final File dbPath = context.getDatabasePath(databaseName);

    // If the database already exists, return
    if (dbPath.exists()) {
        Log.d("Activity", "db Path Exists");
        return;
    }

    // Make sure we have a path to the file
    dbPath.getParentFile().mkdirs();

    // Try to copy database file
    try {
        final InputStream inputStream = context.getAssets().open(databaseName);
        final OutputStream output = new FileOutputStream(dbPath);

        byte[] buffer = new byte[8192];
        int length;

        while ((length = inputStream.read(buffer, 0, 8192)) > 0) {
            output.write(buffer, 0, length);
        }

        output.flush();
        output.close();
        inputStream.close();
    }
    catch (IOException e) {
        Log.d("Activity", "Failed to open file", e);
        e.printStackTrace();
    }
}

}


you just copy assets/databases to app/databases
and than add addMigrations() in databaseBuilder
it will keep your data

참고URL : https://stackoverflow.com/questions/44263891/how-to-use-room-persistence-library-with-pre-populated-database

반응형