会议室数据库迁移 - 位图

Room Database Migration - Bitmap

提问人:burhanyaprak 提问时间:9/26/2022 最后编辑:burhanyaprak 更新时间:10/16/2023 访问量:465

问:

我正在使用 Room 数据库,我更新了我的模型。这就是我进行迁移的原因,以便不会删除现有数据。我尝试在迁移时在 SQL 代码中添加位图,但出现错误。如何使用 SQL 代码添加位图?

型:

@Entity(tableName = "person_table")
data class PersonModel(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val name: String,
    val surname: String,
    val profilePicture: Bitmap
)

数据库:

@Database(entities = [PersonModel::class], version = 2, exportSchema = true)
@TypeConverters(Converter::class)
abstract class PersonDatabase : RoomDatabase() {
    abstract fun personDao(): PersonDao

    companion object {

        @Volatile
        private var INSTANCE: PersonDatabase? = null

        fun getDatabase(context: Context): PersonDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    PersonDatabase::class.java,
                    "PersonDatabase"
                ).addMigrations(MIGRATION_1_2)
                    .build()
                INSTANCE = instance
                instance
            }
        }

        val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL(
                    "ALTER TABLE person_table ADD COLUMN profilePicture BITMAP"
                )
            }
        }
    }
}

转炉:

class Converter {

    @TypeConverter
    fun fromBitmap(bitmap: Bitmap): ByteArray {
        val outputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
        return outputStream.toByteArray()
    }

    @TypeConverter
    fun toBitmap(byteArray: ByteArray): Bitmap {
        return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
    }

}
Android SQL Kotlin android-room 数据库迁移

评论


答:

2赞 Александр Волошиновский 9/26/2022 #1

Room 不支持位图,但支持 BLOB 类型,因此您可以像这样使用

@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
val profilePicture: ByteArray? = null

并添加扩展名以将位图转换为字节数组

fun Bitmap.toByteArray(quality: Int = 50): ByteArray {
    val stream = ByteArrayOutputStream()
    compress(Bitmap.CompressFormat.JPEG, quality, stream)
    return stream.toByteArray()
}
1赞 zeroDivider 10/13/2023 #2

如@Александр所述,Room 不支持位图,但支持 BLOB 类型。 据此,您提供的解决方案中有两个错误:

val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL(
            "ALTER TABLE person_table ADD COLUMN profilePicture BLOB DEFAULT NULL"
        )
    }
}

因此,它应该代替 ,然后:BLOBBITMAP

@Entity(tableName = "person_table")
data class PersonModel(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val name: String,
    val surname: String,
    @ColumnInfo(typeAffinity = ColumnInfo.BLOB)
    val profilePicture: Bitmap?
)

它仍然可以是,但您应该添加,这里是转换器:BitmaptypeAffinity

    @TypeConverter
    fun bitmapToByteArray(bitmap: Bitmap?): ByteArray {
        val byteArrayOutputStream = ByteArrayOutputStream()
        bitmap?.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)
        return byteArrayOutputStream.toByteArray()
    }

    @TypeConverter
    fun byteArrayToBitmap(byteArray: ByteArray?): Bitmap? {
        return BitmapFactory.decodeByteArray(
            byteArray ?: ByteArrayOutputStream().toByteArray(),
            0,
            byteArray?.size ?: 0
        )
    }

但@Александр的解决方案也行得通,:)