หากต้องการให้แอปเริ่มต้นด้วยฐานข้อมูลที่มีชุดข้อมูลที่เฉพาะเจาะจงโหลดไว้แล้ว คุณสามารถป้อนข้อมูลล่วงหน้าในฐานข้อมูลได้ ใน Room คุณสามารถใช้ API เพื่อป้อนข้อมูลล่วงหน้าในฐานข้อมูลเมื่อเริ่มต้นด้วยเนื้อหาจากไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าในระบบไฟล์ของอุปกรณ์
ป้อนข้อมูลล่วงหน้าจากชิ้นงานแอป
หากต้องการป้อนข้อมูลล่วงหน้าในฐานข้อมูล Room จากไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าซึ่งอยู่ใน
ไดเรกทอรี assets/ ของแอป ให้เรียกใช้createFromAsset
ฟังก์ชันจากออบเจ็กต์ RoomDatabase.Builder ก่อนที่จะเรียกใช้ build
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .build()
ฟังก์ชัน createFromAsset รับอาร์กิวเมนต์สตริงที่มีเส้นทางแบบสัมพัทธ์จากไดเรกทอรี assets/ ไปยังไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้า
ป้อนข้อมูลล่วงหน้าจากระบบไฟล์
หากต้องการป้อนข้อมูลล่วงหน้าในฐานข้อมูล Room จากไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าซึ่งอยู่ในระบบไฟล์ของอุปกรณ์
ยกเว้นไดเรกทอรีassets/ของแอป
ให้เรียกใช้ฟังก์ชันcreateFromFileจากออบเจ็กต์RoomDatabase.Builder
ก่อนที่จะเรียกใช้build:
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromFile(File("mypath")) .build()
ฟังก์ชัน createFromFile รับอาร์กิวเมนต์ File สำหรับไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้า
Room จะสร้างสำเนาของไฟล์ที่กำหนดแทนที่จะเปิดไฟล์โดยตรง ดังนั้นตรวจสอบว่าแอปมีสิทธิ์อ่านไฟล์
จัดการการย้ายข้อมูลที่มีฐานข้อมูลที่บรรจุไว้ล่วงหน้า
ไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้ายังสามารถเปลี่ยนวิธีที่ฐานข้อมูล Room จัดการการย้ายข้อมูลสำรองได้ด้วย โดยปกติแล้ว เมื่อเปิดใช้การย้ายข้อมูลแบบทำลายล้าง และ Room ต้องทำการย้ายข้อมูลโดยไม่มีเส้นทางการย้ายข้อมูล Room จะลบ ตารางทั้งหมดในฐานข้อมูลและสร้างฐานข้อมูลที่ว่างเปล่าด้วยสคีมาที่ระบุ สำหรับเวอร์ชันเป้าหมาย อย่างไรก็ตาม หากคุณรวมไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าที่มีหมายเลขเดียวกันกับเวอร์ชันเป้าหมาย Room จะป้อนข้อมูลในฐานข้อมูลที่สร้างขึ้นใหม่ด้วยเนื้อหาของไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าหลังจากทำการย้ายข้อมูลแบบทำลายล้าง
ดูข้อมูลเพิ่มเติมเกี่ยวกับการย้ายข้อมูลฐานข้อมูล Room ได้ที่หัวข้อ ย้ายข้อมูลฐานข้อมูล Room
ส่วนต่อไปนี้จะแสดงตัวอย่างเล็กน้อยเกี่ยวกับวิธีที่การย้ายข้อมูลทำงานในทางปฏิบัติ
ตัวอย่าง: การย้ายข้อมูลสำรองด้วยฐานข้อมูลที่บรรจุไว้ล่วงหน้า
สมมติว่า
- แอปของคุณกำหนดฐานข้อมูล Room ในเวอร์ชัน 3
- อินสแตนซ์ฐานข้อมูลที่ติดตั้งไว้ในอุปกรณ์เป็นเวอร์ชัน 2
- มีไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าซึ่งเป็นเวอร์ชัน 3
- ไม่มีเส้นทางการย้ายข้อมูลที่ใช้งานได้จากเวอร์ชัน 2 ไปยังเวอร์ชัน 3
- เปิดใช้การย้ายข้อมูลแบบทำลายล้าง
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class FallbackAppDatabase : RoomDatabase() { // ... } fun createFallbackDb(appContext: Context) { Room.databaseBuilder<FallbackAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .fallbackToDestructiveMigration() .build() }
สิ่งที่จะเกิดขึ้นในสถานการณ์นี้
- เนื่องจากฐานข้อมูลที่กำหนดไว้ในแอปเป็นเวอร์ชัน 3 และอินสแตนซ์ฐานข้อมูลที่ติดตั้งไว้ในอุปกรณ์เป็นเวอร์ชัน 2 จึงจำเป็นต้องมีการย้ายข้อมูล
- เนื่องจากไม่มีแผนการย้ายข้อมูลที่ใช้งานได้จากเวอร์ชัน 2 ไปยังเวอร์ชัน 3 การย้ายข้อมูลจึงเป็นการย้ายข้อมูลสำรอง
- เนื่องจากคุณเรียกใช้ฟังก์ชัน Builder
fallbackToDestructiveMigrationการย้ายข้อมูลสำรองจึงเป็นการย้ายข้อมูลแบบทำลายล้าง Room จะลบอินสแตนซ์ฐานข้อมูลที่ติดตั้งไว้ในอุปกรณ์ - เนื่องจากมีไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าซึ่งเป็นเวอร์ชัน 3 Room จะสร้างฐานข้อมูลขึ้นใหม่และป้อนข้อมูลโดยใช้เนื้อหาของไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้า หากไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าเป็นเวอร์ชัน 2 Room จะพิจารณาว่าไฟล์ดังกล่าวไม่ตรงกับเวอร์ชันเป้าหมายและจะไม่ใช้ไฟล์ดังกล่าวสำหรับการย้ายข้อมูลสำรอง
ตัวอย่าง: การย้ายข้อมูลที่ใช้งานได้ด้วยฐานข้อมูลที่บรรจุไว้ล่วงหน้า
สมมติว่าแอปของคุณใช้งานเส้นทางการย้ายข้อมูลจากเวอร์ชัน 2 ไปยังเวอร์ชัน 3
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class ImplementedAppDatabase : RoomDatabase() { // ... } // Migration path definition from version 2 to version 3. val MIGRATION_2_3 = object : Migration(2, 3) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createImplementedDb(appContext: Context) { Room.databaseBuilder<ImplementedAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_2_3) .build() }
สิ่งที่จะเกิดขึ้นในสถานการณ์นี้
- เนื่องจากฐานข้อมูลที่กำหนดไว้ในแอปเป็นเวอร์ชัน 3 และฐานข้อมูลที่ติดตั้งไว้ในอุปกรณ์เป็นเวอร์ชัน 2 จึงจำเป็นต้องมีการย้ายข้อมูล
- เนื่องจากมีเส้นทางการย้ายข้อมูลที่ใช้งานได้จากเวอร์ชัน 2 ไปยังเวอร์ชัน 3,
Room จะเรียกใช้ฟังก์ชัน
migrateที่กำหนดไว้เพื่ออัปเดตอินสแตนซ์ฐานข้อมูล ในอุปกรณ์เป็นเวอร์ชัน 3 โดยเก็บรักษาข้อมูลที่มีอยู่ใน ฐานข้อมูลไว้ Room จะไม่ใช้ไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้า เนื่องจาก Room จะใช้ไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าในกรณีของการย้ายข้อมูลสำรองเท่านั้น
ตัวอย่าง: การย้ายข้อมูลหลายขั้นตอนด้วยฐานข้อมูลที่บรรจุไว้ล่วงหน้า
ไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้ายังส่งผลต่อการย้ายข้อมูลที่มีหลายขั้นตอนได้ด้วย พิจารณากรณีต่อไปนี้
- แอปของคุณกำหนดฐานข้อมูล Room ในเวอร์ชัน 4
- อินสแตนซ์ฐานข้อมูลที่ติดตั้งไว้ในอุปกรณ์เป็นเวอร์ชัน 2
- มีไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าซึ่งเป็นเวอร์ชัน 3
- มีเส้นทางการย้ายข้อมูลที่ใช้งานได้จากเวอร์ชัน 3 ไปยังเวอร์ชัน 4 แต่ไม่มีจากเวอร์ชัน 2 ไปยังเวอร์ชัน 3
- เปิดใช้การย้ายข้อมูลแบบทำลายล้าง
// Database class definition declaring version 4. @Database(entities = [SampleEntity::class], version = 4) abstract class MultiStepAppDatabase : RoomDatabase() { // ... } val MIGRATION_3_4 = object : Migration(3, 4) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createMultiStepDb(appContext: Context) { Room.databaseBuilder<MultiStepAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_3_4) .fallbackToDestructiveMigration() .build() }
สิ่งที่จะเกิดขึ้นในสถานการณ์นี้
- เนื่องจากฐานข้อมูลที่กำหนดไว้ในแอปเป็นเวอร์ชัน 4 และอินสแตนซ์ฐานข้อมูลที่ติดตั้งไว้ในอุปกรณ์เป็นเวอร์ชัน 2 จึงจำเป็นต้องมีการย้ายข้อมูล
- เนื่องจากไม่มีเส้นทางการย้ายข้อมูลที่ใช้งานได้จากเวอร์ชัน 2 ไปยังเวอร์ชัน 3 การย้ายข้อมูลจึงเป็นการย้ายข้อมูลสำรอง
- เนื่องจากคุณเรียกใช้ฟังก์ชัน Builder
fallbackToDestructiveMigrationการย้ายข้อมูลสำรองจึงเป็นการย้ายข้อมูลแบบทำลายล้าง Room จะลบอินสแตนซ์ฐานข้อมูลในอุปกรณ์ - เนื่องจากมีไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าซึ่งเป็นเวอร์ชัน 3 Room จะสร้างฐานข้อมูลขึ้นใหม่และป้อนข้อมูลโดยใช้เนื้อหาของไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้า
- ฐานข้อมูลที่ติดตั้งไว้ในอุปกรณ์เป็นเวอร์ชัน 3 แล้ว เนื่องจากยังต่ำกว่าเวอร์ชันที่กำหนดไว้ในแอป จึงจำเป็นต้องมีการย้ายข้อมูลอีกครั้ง
- เนื่องจากมีเส้นทางการย้ายข้อมูลที่ใช้งานได้จากเวอร์ชัน 3 ไปยังเวอร์ชัน 4
Room จะเรียกใช้ฟังก์ชัน
migrateที่กำหนดไว้เพื่ออัปเดตอินสแตนซ์ฐานข้อมูล ในอุปกรณ์เป็นเวอร์ชัน 4 โดยเก็บรักษาข้อมูลที่คัดลอก มาจากไฟล์ฐานข้อมูลที่บรรจุไว้ล่วงหน้าเวอร์ชัน 3 ไว้