在android Room中更新实体的某些特定字段

Ras*_*sel 92 android sql-update android-room

我正在为我的新项目使用android房间持久性库.我想更新一些表的字段.我试过像我一样Dao-

// Method 1:

@Dao
public interface TourDao {
    @Update
    int updateTour(Tour tour);
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用此方法进行更新时,它会更新实体中与tour对象的主键值匹配的每个字段.我用过@Query

// Method 2:

@Query("UPDATE Tour SET endAddress = :end_address WHERE id = :tid")
int updateTour(long tid, String end_address);
Run Code Online (Sandbox Code Playgroud)

它正在工作,但在我的案例中会有很多查询,因为我的实体中有很多字段.我想知道如何更新某些字段(不是全部),例如Method 1id = 1; (id是自动生成主键).

// Entity:

@Entity
public class Tour {
    @PrimaryKey(autoGenerate = true)
    public long id;
    private String startAddress;
    private String endAddress;
    //constructor, getter and setter
}
Run Code Online (Sandbox Code Playgroud)

geo*_*sey 68

从2019 年 10 月发布的Room 2.2.0 开始,您可以为更新指定目标实体。那么如果更新参数不同,Room 只会更新部分实体列。OP 问题的示例将更清楚地显示这一点。

@Update(entity = Tour::class)
fun update(obj: TourUpdate)

@Entity
public class TourUpdate {
    @ColumnInfo(name = "id")
    public long id;
    @ColumnInfo(name = "endAddress")
    private String endAddress;
}
Run Code Online (Sandbox Code Playgroud)

请注意,您必须创建一个名为 TourUpdate 的新部分实体,以及问题中的真实 Tour 实体。现在,当您使用 TourUpdate 对象调用 update 时,它​​将更新 endAddress 并使 startAddress 值保持不变。这非常适合我在 DAO 中使用 insertOrUpdate 方法的用例,该方法使用来自 API 的新远程值更新数据库,但将本地应用程序数据单独留在表中。

  • 有趣的方式 (2认同)
  • 根据[Room文档](https://developer.android.com/reference/androidx/room/Update),部分实体没有用`@Entity`或`@ColumnInfo`注释,但你可以使用普通的波乔。 (2认同)

Jur*_*lja 56

根据SQLite更新文档 :

<!-- language: lang-java -->
@Query("UPDATE tableName SET 
    field1 = :value1,
    field2 = :value2, 
    ...
    //some more fields to update
    ...
    field_N= :value_N
    WHERE id = :id)

int updateTour(long id, 
               Type value1, 
               Type value2, 
               ... ,
               // some more values here
               ... ,
               Type value_N);
Run Code Online (Sandbox Code Playgroud)

例:

实体:

@Entity(tableName = "orders")
public class Order {

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

@ColumnInfo(name = "order_title")
private String title;

@ColumnInfo(name = "order_amount")
private Float amount;

@ColumnInfo(name = "order_price")
private Float price;

@ColumnInfo(name = "order_desc")
private String description;

// ... methods, getters, setters
}
Run Code Online (Sandbox Code Playgroud)

道:

@Dao
public interface OrderDao {

@Query("SELECT * FROM orders")
List<Order> getOrderList();

@Query("SELECT * FROM orders")
LiveData<List<Order>> getOrderLiveList();

@Query("SELECT * FROM orders WHERE order_id =:orderId")
LiveData<Order> getLiveOrderById(int orderId);

/**
* Updating only price
* By order id
*/
@Query("UPDATE orders SET order_price=:price WHERE order_id = :id")
void update(Float price, int id);

/**
* Updating only amount and price
* By order id
*/
@Query("UPDATE orders SET order_amount = :amount, price = :price WHERE order_id =:id")
void update(Float amount, Float price, int id);

/**
* Updating only title and description
* By order id
*/
@Query("UPDATE orders SET order_desc = :description, order_title= :title WHERE order_id =:id")
void update(String description, String title, int id);

@Update
void update(Order order);

@Delete
void delete(Order order);

@Insert(onConflict = REPLACE)
void insert(Order order);
}
Run Code Online (Sandbox Code Playgroud)

  • 您能再解释一下吗? (3认同)
  • 我的意思是在您的解决方案中 :) 最好将它放在那里供其他用户查看 (2认同)

Com*_*are 50

我想知道如何更新某些字段(不是全部),如方法1,其中id = 1

使用@Query方法2中的方法.

在我的情况下查询太长,因为我的实体中有很多字段

然后有更小的实体.或者,不要单独更新字段,而是与数据库进行更粗粒度的交互.

IOW,房间本身没有什么可以做你想要的.

  • Room 2.2.0-alpha01 (https://developer.android.com/jetpack/androidx/releases/room#2.2.0-alpha01) 为 @Update 引入了一个新参数,可让您设置目标实体。这应该可以实现部分更新。 (4认同)

J.D*_*gon 7

我认为您不需要只更新某些特定字段。只需更新整个数据即可。

@更新查询

基本上这是一个给定的查询。无需进行新的查询。

@Dao
interface MemoDao {

    @Insert
    suspend fun insert(memo: Memo)

    @Delete
    suspend fun delete(memo: Memo)

    @Update
    suspend fun update(memo: Memo)
}
Run Code Online (Sandbox Code Playgroud)

备忘录类

@Entity
data class Memo (
    @PrimaryKey(autoGenerate = true) val id: Int,
    @ColumnInfo(name = "title") val title: String?,
    @ColumnInfo(name = "content") val content: String?,
    @ColumnInfo(name = "photo") val photo: List<ByteArray>?
)
Run Code Online (Sandbox Code Playgroud)

您唯一需要知道的是“id”。例如,如果您只想更新“标题”,则可以重复使用已插入数据中的“内容”和“照片”。 在实际代码中,像这样使用

val memo = Memo(id, title, content, byteArrayList)
memoViewModel.update(memo)
Run Code Online (Sandbox Code Playgroud)


Sup*_*Yao 5

也许您可以尝试一下,但是性能会稍差一些(或更多):

@Dao
public abstract class TourDao {

    @Query("SELECT * FROM Tour WHERE id == :id")
    public abstract Tour getTour(int id);

    @Update
    public abstract int updateTour(Tour tour);

    public void updateTour(int id, String end_address) {
        Tour tour = getTour(id);
        tour.end_address = end_address;
        updateTour(tour);
    }
}
Run Code Online (Sandbox Code Playgroud)