http://en.wikipedia.org/wiki/Upsert
在SQLite中有没有一些我没想到的聪明方法?
基本上,如果记录存在,我想更新四列中的三列,如果它不存在,我想用第四列的默认(NUL)值插入记录.
ID是主键,因此UPSERT只会有一条记录.
(我试图避免SELECT的开销,以确定我是否需要更新或插入显然)
建议?
我无法在SQLite网站上确认SQL CREATE的语法.我还没有构建一个演示来测试它,但它似乎不支持..
如果是,我有三列,所以它实际上看起来像:
CREATE TABLE table1(
id INTEGER PRIMARY KEY ON CONFLICT REPLACE,
Blob1 BLOB ON CONFLICT REPLACE,
Blob2 BLOB ON CONFLICT REPLACE,
Blob3 BLOB
);
Run Code Online (Sandbox Code Playgroud)
但是前两个blob不会引起冲突,只有ID会因此我asusme Blob1和Blob2不会被替换(根据需要)
绑定数据时SQLite中的UPDATE是一个完整的事务,这意味着每个要更新的发送行都需要:Prepare/Bind/Step/Finalize语句,与允许使用重置函数的INSERT不同
语句对象的生命周期如下:
更新我猜测与INSERT相比速度慢,但它与使用主键的SELECT相比如何呢?
也许我应该使用select来读取第4列(Blob3),然后使用REPLACE编写一条新记录,将原始的第4列与前3列的新数据混合在一起?
我需要更新,如果不存在,则插入行到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或插入的行?
从我所读的内容Room不允许您在主线程上发出数据库查询(因为可能导致主线程的延迟)). 所以想象一下,我正在尝试更新UI主线程上的textview哪些数据如何才能收到回调.让我举个例子.想象一下,我想将我的业务模型数据存储到一个名为Events的对象中.因此我们有一个EventDao对象:
想象我们在下面有这个DAO对象:
@Dao
public interface EventDao {
@Query("SELECT * FROM " + Event.TABLE_NAME + " WHERE " + Event.DATE_FIELD + " > :minDate" limit 1)
LiveData<List<Event>> getEvent(LocalDateTime minDate);
@Insert(onConflict = REPLACE)
void addEvent(Event event);
@Delete
void deleteEvent(Event event);
@Update(onConflict = REPLACE)
void updateEvent(Event event);
}
Run Code Online (Sandbox Code Playgroud)
现在在一些活动中,我有一个textview,我想更新它的值,所以我这样做:
myTextView.setText(EventDao.getEvent(someDate));/*i think this is illegal as im trying to call room dao on mainthread, therefore how is this done correctly ? would i need to show a spinner while it updates ?*/ …Run Code Online (Sandbox Code Playgroud) 我有几个定期从服务器更新的表 ( Benefit, Branch, Coupon) 和另外两个仅本地的表 ( FavoriteBenefit, UsedCoupon)。ER图如下所示:

每当Benefit在服务器上删除a 时,我还想从FavoriteBenefit. 为此,我可以使用onDelete = ForeignKey.CASCADE,每当Benefit数据库中不再存在父级时,它FavoriteBenefit也会被删除。听起来不错。
每当我@Insert(onConflict = OnConflictStrategy.REPLACE)用来更新数据库中的好处时就会出现问题
。REPLACE实际上是一个执行DELETE和INSERT,但DELETE在内部触发onDelete的FavoriteBenefit,因此,在该表中的所有数据被删除。
(Coupon和UsedCoupon表也会出现类似的问题。)
我正在寻找一种方法来暂时禁用外键约束,直到事务结束。也就是说,不要在事务期间验证外键,而只在事务结束时验证。我仍然希望 Room 自动删除没有有效父级的实体。
似乎通过在定义上设置将外键标记为延迟应该完全符合我想要实现的目标。deferred = true@ForeignKey
布尔延迟 ()
外键约束可以推迟到事务完成。如果您在单个事务中对数据库进行批量插入,这将非常有用。默认情况下,外键约束是即时的,但您可以通过将此字段设置为 true 来更改它。
但即使我设置了deferred标志,它似乎也没有效果,因为FavoriteBenefit每次仍然被删除。
我是否deferred错误地理解了标志?