-->

How insert image in room persistence library?

2019-03-13 04:05发布

问题:

I am using room persistence library for my android application, Now I have to insert image in my db. I successfully define @Entity for the primitive data type. and also through converter class, i stored all object, date, time. Now I have to store Image. I am not able to understand how we define Column info and entity and how we insert that data as well as read data from the table.

What is the maximum size of data which inserted into the single row? What is max and min size of data in one field in Android SQLite?

回答1:

It is usually not recommended to store image data into the database. But however if it is required for your project then you can do so.

Image data are usually stored into db using BLOB data type, Room also provide support for BLOB data type Documentation

You can declare your entity class as mentioned below to store Image data.

@Entity(tableName = "test")
public class Test{

@PrimaryKey
@ColumnInfo(name = "_id")
private int id;

@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
private byte[] image;
}


回答2:

As Pinakin mentioned, it is not recommended to store an image into database and file path would be better but if it is required to store image I would suggest compress the image to below 2 MB (here is an example) to avoid breaking app. Room supports BLOB for image. Entity class in kotlin:

ImageTest.kt

 @Entity    
 class ImageTest {

        @PrimaryKey(autoGenerate = true)

        var id: Int = 1

        @ColumnInfo(typeAffinity = ColumnInfo.BLOB)
        var data: ByteArray? = null
      }

ImageDao.kt

 @Dao
 interface ImageTestDao {

       @Insert(onConflict = OnConflictStrategy.REPLACE)
       fun upsertByReplacement(image: List<ImageTest>)

       @Query("SELECT * FROM image")
       fun getAll(): List<ImageTest>

       @Query("SELECT * FROM image WHERE id IN (:arg0)")
       fun findByIds(imageTestIds: List<Int>): List<ImageTest>

       @Delete
       fun delete(imageTest: ImageTest)
   }

Databse.kt

 import android.arch.persistence.room.Database
 import android.arch.persistence.room.RoomDatabase
 import android.arch.persistence.room.TypeConverters

   @Database(entities = arrayOf(ImageTest::class), version = 1)
   @TypeConverters(DataConverters::class)
   abstract class Database : RoomDatabase() {
    abstract fun getImageTestDao(): ImageTestDao
   }

In DatabaseHelper something like

  class DatabaseHelper(context: Context) {

   init {
        DatabaseHelper.context = WeakReference(context)
        }

   companion object {

   private var context: WeakReference<Context>? = null
   private const val DATABASE_NAME: String = "image_test_db"
   private var singleton: Database? = null

   private fun createDatabase(): Database {
       return Room.databaseBuilder(context?.get() ?:
               throw IllegalStateException("initialize by calling  
               constructor before calling DatabaseHelper.instance"),
               Database::class.java,
               DATABASE_NAME)
               .build()
   }


   val instance: Database
       @Synchronized get() {
           if (null == singleton)
               singleton = createDatabase()

           return singleton as Database
       }

     fun setImage(img: Bitmap){
     val dao = DatabaseHelper.instance.getImageTestDao() 
     val imageTest = ImageTest()
     imageTest.data = getBytesFromImageMethod(image)//TODO
     dao.updsertByReplacement(imageTest)

     fun getImage():Bitmap?{
     val dao = DatabaseHelper.instance.getImageTestDao() 
     val imageByteArray = dao.getAll()
     return loadImageFromBytes(imageByteArray[0].data)
     //change accordingly 
     }

Correct me if I am wrong. Hope this helps someone out there