ip6*_*696 21 android android-room
我需要更新,如果不存在,则插入行到ROOM DB.
我这样做: productRepository.updateProducts(productsResponse.getProductItems());
和:
@Override
public void updateProducts(final List<ProductItem> products) {
new Thread(() -> {
for (ProductItem item : products) {
Product product = createProduct(item);
productDao.insert(product);
}
}).start();
}
Run Code Online (Sandbox Code Playgroud)
在DAO中:
@Insert
void insert(Product products);
Run Code Online (Sandbox Code Playgroud)
但我有方法
@Update
void update(Product product);
Run Code Online (Sandbox Code Playgroud)
我有一些问题:
两种方法都是无效的.插入后如何返回保存的Product或boolean flag或insert count?
如果我试着打电话update而且我没有排它会插入吗?
如何更新(如果不是 - 插入)行和返回计数updatet或插入的行?
Dan*_*iev 37
一个带注释的方法@Insert可以返回一个long.这是插入行的新生成的ID.一个带注释的方法@Update可以返回一个int.这是更新行的数量.
update将尝试使用where子句中主键的值更新所有字段.如果您的实体尚未保留在数据库中,则update查询将无法找到行并且不会更新任何内容.
你可以用@Insert(onConflict = OnConflictStrategy.REPLACE).这将尝试插入实体,如果存在具有相同ID值的现有行,它将删除它并将其替换为您尝试插入的实体.请注意,如果您使用自动生成的ID,则意味着生成的行将具有与替换的原始ID不同的ID.如果你想保留ID,那么你必须想出一个自定义的方法来做到这一点.
Umy*_*Umy 10
更新。
@Upsert 添加到 Room 2.5.0-alpha03。无需重新发明轮子)
感谢@Ashwini 的好主意。
@Dao
interface SendDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(model: DataModel): Long
@Update
suspend fun update(model: DataModel): Int
@Transaction
suspend fun insertOrUpdate(model: DataModel): Long {
val id = insert(model)
return if (id==-1L) {
update(model)
model.id
} else {
id
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以我们应该调用:database.sendDao().insertOrUpdate(DataModel(...))
已经有一段时间了,但是这个问题没有一个可以接受的答案,所以我会考虑一下。
至于@Danail Alexiev说 @Insert可以返回long。@Update可以传回int。
但是,您出于什么目的使用更新?如果您只想用新对象替换整个对象,则只需指定OnConflictStrategy
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Product products);
Run Code Online (Sandbox Code Playgroud)
结果将是:将添加不存在的项目,将已存在的项目替换为新项目。
如果您只需要更新一个参数(例如数量),则可以执行以下操作
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Product products);
@Query("SELECT * from item WHERE id= :id")
void getItemById(int id): List<Product>
@Query("UPDATE item SET quantity = quantity + 1 WHERE id = :id")
void updateQuantity(int id)
void insertOrUpdate(Product item) {
Product itemFromDB = getItemById(item.getId())
if (itemFromDB == null)
insert(item)
else
updateQuantity(item.getId())
}
}
Run Code Online (Sandbox Code Playgroud)
结果将是:尝试在数据库中查找项目,如果发现更新属性,则不只是插入一个新项目。因此,您只需insertOrUpdate要从DAO 调用一种方法。
如果已经有具有特定字段的项目,您可以检查您的数据库,例如:
@Query("SELECT id FROM items WHERE id = :id LIMIT 1")
fun getItemId(id: String): String?
@Insert
fun insert(item: Item): Long
@Update(onConflict = OnConflictStrategy.REPLACE)
fun update(item: Item): Int
Run Code Online (Sandbox Code Playgroud)
Item 是您的对象,在您的代码中:
fun insertOrUpdate(item: Item) {
database.runInTransaction {
val id = getItemDao().getItemId(item.id)
if(id == null)
getItemDao().insert(item)
else
getItemDao().update(item)
}
}
Run Code Online (Sandbox Code Playgroud)
你可以使用@Upsert
def room_version = "2.5.0-beta01" // or later
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
@Upsert(entity = Show::class)
fun updateOrInsert(shows: List<ShowUpdate>)
@Entity
data class Show(
@PrimaryKey var id: Int = 0,
val title: String? = null,
val imageUrl: String? = null,
val timestamp: Long = System.currentTimeMillis(),
val isFavorite: Boolean? = false
)
Run Code Online (Sandbox Code Playgroud)
这仅更新 Show 的某些字段。不更新字段isFavorite
@Entity
data class ShowUpdate(
@PrimaryKey var id: Int = 0,
val title: String? = null,
val imageUrl: String? = null,
val timestamp: Long = System.currentTimeMillis()
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29961 次 |
| 最近记录: |