Android Room Persistence Library: Upsert

前端 未结 9 575
太阳男子
太阳男子 2020-12-12 10:50

Android\'s Room persistence library graciously includes the @Insert and @Update annotations that work for objects or collections. I however have a use case (push notificatio

相关标签:
9条回答
  • 2020-12-12 11:42

    If you have legacy code: some entities in Java and BaseDao as Interface (where you cannot add a function body) or you too lazy for replacing all implements with extends for Java-children.

    Note: It works only in Kotlin code. I'm sure that you write new code in Kotlin, I'm right? :)

    Finally a lazy solution is to add two Kotlin Extension functions:

    fun <T> BaseDao<T>.upsert(entityItem: T) {
        if (insert(entityItem) == -1L) {
            update(entityItem)
        }
    }
    
    fun <T> BaseDao<T>.upsert(entityItems: List<T>) {
        val insertResults = insert(entityItems)
        val itemsToUpdate = arrayListOf<T>()
        insertResults.forEachIndexed { index, result ->
            if (result == -1L) {
                itemsToUpdate.add(entityItems[index])
            }
        }
        if (itemsToUpdate.isNotEmpty()) {
            update(itemsToUpdate)
        }
    }
    
    0 讨论(0)
  • 2020-12-12 11:43

    This is the code in Kotlin:

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(entity: Entity): Long
    
    @Update(onConflict = OnConflictStrategy.REPLACE)
    fun update(entity: Entity)
    
    @Transaction
    fun upsert(entity: Entity) {
      val id = insert(entity)
       if (id == -1L) {
         update(entity)
      }
    }
    
    0 讨论(0)
  • 2020-12-12 11:46

    Another approach I can think of is to get the entity via DAO by query, and then perform any desired updates. This may be less efficient compared to the other solutions in this thread in terms of runtime because of having to retrieve the full entity, but allows much more flexibility in terms of operations allowed such as on what fields/variable to update.

    For example :

    private void upsert(EntityA entityA) {
       EntityA existingEntityA = getEntityA("query1","query2");
       if (existingEntityA == null) {
          insert(entityA);
       } else {
          entityA.setParam(existingEntityA.getParam());
          update(entityA);
       }
    }
    
    0 讨论(0)
提交回复
热议问题