Actualizar algún campo específico de una entidad en Android Room
Estoy usando la biblioteca de persistencia de la sala de Android para mi nuevo proyecto. Quiero actualizar algún campo de la tabla. Lo he intentado como en mi Dao
-
// Method 1:
@Dao
public interface TourDao {
@Update
int updateTour(Tour tour);
}
Pero cuando intento actualizar usando este método, actualiza todos los campos de la entidad donde coincide con el valor de la clave principal del objeto del recorrido. He usado@Query
// Method 2:
@Query("UPDATE Tour SET endAddress = :end_address WHERE id = :tid")
int updateTour(long tid, String end_address);
Está funcionando pero habrá muchas consultas en mi caso porque tengo muchos campos en mi entidad. Quiero saber cómo puedo actualizar algún campo (no todos) como Method 1
donde id = 1; (La identificación es la clave principal de generación automática).
// Entity:
@Entity
public class Tour {
@PrimaryKey(autoGenerate = true)
public long id;
private String startAddress;
private String endAddress;
//constructor, getter and setter
}
Según los documentos de actualización de 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);
Ejemplo:
Entidad:
@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
}
Tao:
@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);
}
A partir de la Sala 2.2.0 lanzada en octubre de 2019, puede especificar una entidad de destino para las actualizaciones. Luego, si el parámetro de actualización es diferente, Room solo actualizará las columnas de entidad parciales. Un ejemplo de la pregunta OP mostrará esto un poco más claramente.
@Update(entity = Tour::class)
fun update(obj: TourUpdate)
@Entity
public class TourUpdate {
@ColumnInfo(name = "id")
public long id;
@ColumnInfo(name = "endAddress")
private String endAddress;
}
Tenga en cuenta que debe crear una nueva entidad parcial llamada TourUpdate, junto con su entidad Tour real en la pregunta. Ahora, cuando llame a actualizar con un objeto TourUpdate, actualizará endAddress y dejará el valor startAddress igual. Esto funciona perfecto para mí en mi caso de uso de un método insertOrUpdate en mi DAO que actualiza la base de datos con nuevos valores remotos de la API pero deja los datos de la aplicación local solos en la tabla.