새 프로젝트에 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
}
답변
ID = 1 인 방법 1과 같은 일부 필드 (전부는 아님)를 어떻게 업데이트 할 수 있는지 알고 싶습니다.
@Query
방법 2에서와 같이를 사용하십시오 .
내 엔터티에 필드가 많기 때문에 내 경우에는 쿼리가 너무 깁니다.
그런 다음 더 작은 개체가 있습니다. 또는 필드를 개별적으로 업데이트하지 말고 대신 데이터베이스와보다 대략적으로 상호 작용하십시오.
IOW, Room 자체에는 원하는 것을 수행 할 수있는 것이 없습니다.
답변
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);
예:
실재:
@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 :
@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);
}
답변
현재 룸 2.2.0 2019년 10월 발표, 당신은 업데이트 대상 법인을 지정할 수 있습니다. 그런 다음 업데이트 매개 변수가 다른 경우 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;
}
질문의 실제 Tour 엔터티와 함께 TourUpdate라는 새 부분 엔터티를 만들어야합니다. 이제 TourUpdate 개체로 update를 호출하면 endAddress가 업데이트되고 startAddress 값은 그대로 유지됩니다. 이것은 API의 새로운 원격 값으로 DB를 업데이트하지만 로컬 앱 데이터를 테이블에 그대로 두는 DAO의 insertOrUpdate 메서드 사용 사례에 적합합니다.
답변
시도해 볼 수는 있지만 성능이 조금 더 나빠질 수 있습니다.
@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);
}
}
답변
특정 필드 만 업데이트 할 필요는 없다고 생각합니다. 전체 데이터를 업데이트하기 만하면됩니다.
@ 업데이트 쿼리
기본적으로 주어진 쿼리입니다. 새로운 쿼리를 만들 필요가 없습니다.
@Dao
interface MemoDao {
@Insert
suspend fun insert(memo: Memo)
@Delete
suspend fun delete(memo: Memo)
@Update
suspend fun update(memo: Memo)
}
Memo.class
@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>?
)
당신이 알아야 할 것은 ‘id’뿐입니다. 예를 들어 ‘제목’만 업데이트하려는 경우 이미 삽입 된 데이터에서 ‘콘텐츠’와 ‘사진’ 을 재사용 할 수 있습니다 .
실제 코드에서는 다음과 같이 사용하십시오.
val memo = Memo(id, title, content, byteArrayList)
memoViewModel.update(memo)
답변
특정 사용자 ID “x”에 대한 사용자 정보를 업데이트해야하는 경우,
- 생성자에서 데이터베이스를 초기화하고 viewModel과 DAO 사이의 중재자 역할을 하는 dbManager 클래스 를 만들어야합니다 .
-
뷰 모델은 데이터베이스에 액세스 할 dbManager의 인스턴스를 초기화합니다. 코드는 다음과 같아야합니다.
@Entity class User{ @PrimaryKey String userId; String username; } Interface UserDao{ //forUpdate @Update void updateUser(User user) } Class DbManager{ //AppDatabase gets the static object o roomDatabase. AppDatabase appDatabase; UserDao userDao; public DbManager(Application application ){ appDatabase = AppDatabase.getInstance(application); //getUserDao is and abstract method of type UserDao declared in AppDatabase //class userDao = appDatabase.getUserDao(); } public void updateUser(User user, boolean isUpdate){ new InsertUpdateUserAsyncTask(userDao,isUpdate).execute(user); } public static class InsertUpdateUserAsyncTask extends AsyncTask<User, Void, Void> { private UserDao userDAO; private boolean isInsert; public InsertUpdateBrandAsyncTask(BrandDAO userDAO, boolean isInsert) { this. userDAO = userDAO; this.isInsert = isInsert; } @Override protected Void doInBackground(User... users) { if (isInsert) userDAO.insertBrand(brandEntities[0]); else //for update userDAO.updateBrand(users[0]); //try { // Thread.sleep(1000); //} catch (InterruptedException e) { // e.printStackTrace(); //} return null; } } } Class UserViewModel{ DbManager dbManager; public UserViewModel(Application application){ dbmanager = new DbMnager(application); } public void updateUser(User user, boolean isUpdate){ dbmanager.updateUser(user,isUpdate); } } Now in your activity or fragment initialise your UserViewModel like this: UserViewModel userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
그런 다음이 방법으로 사용자 항목을 업데이트합니다. 사용자 ID가 1122이고 userName이 “xyz”이며 “zyx”로 변경되어야한다고 가정합니다.
ID 1122 사용자 개체의 userItem 가져 오기
User user = new user(); if(user.getUserId() == 1122){ user.setuserName("zyx"); userViewModel.updateUser(user); }
이것은 원시 코드입니다. 도움이되기를 바랍니다.
즐거운 코딩