web-dev-qa-db-ja.com

Android Roomのエンティティの特定のフィールドを更新します

私は私の新しいプロジェクトのためにAndroidルームパーシスタンスライブラリを使用しています。テーブルのいくつかのフィールドを更新したいです。私はDaoのように試してみました -

// Method 1:

@Dao
public interface TourDao {
    @Update
    int updateTour(Tour tour);
}

しかし、このメソッドを使って更新しようとすると、ツアーオブジェクトの主キー値と一致するエンティティのすべてのフィールドが更新されます。私は@Queryを使いました

// Method 2:

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

これは動作していますが、私のエンティティには多くのフィールドがあるので、私の場合は多くのクエリがあります。 Method 1のようにいくつかのフィールド(全部ではありません)を更新する方法を知りたいです。id = 1; (idは自動生成の主キーです)。

// Entity:

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

方法1のように(すべてではない)いくつかのフィールドを更新する方法を知りたいのですが、id = 1です。

方法2で行ったように、@Queryを使用します。

私の場合は長すぎるクエリです。

それからもっと小さい実体を持ってください。または、フィールドを個別に更新せずに、データベースとのよりきめの粗い対話を使用します。

さて、ルーム自体にはあなたが求めることをするものは何もありません。

39
CommonsWare

SQLite Update Docs によると、

<!-- 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);

例:

エンティティ:

@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
}

ダオ:

@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, intid);

/**
* 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);
}
41
Jurij Pitulja

たぶんあなたはこれを試すことができますが、パフォーマンスは少し(またはそれ以上)悪くなります:

@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);
    }
}
2
SuperYao