Android Room에서 엔티티의 특정 필드를 업데이트합니다.
저는 새로운 프로젝트를 위해 안드로이드 룸 지속성 라이브러리를 사용하고 있습니다.테이블 필드를 업데이트하려고 합니다.나는 내 삶에서 처럼 노력해왔습니다.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
}
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
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);
}
2019년 10월에 공개된 룸 2.2.0부터는 업데이트 대상 엔티티를 지정할 수 있습니다.업데이트 매개변수가 다른 경우, 룸은 부분 도면요소 열만 업데이트합니다.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;
}
질문에 포함된 실제 둘러보기 엔터티와 함께 TourUpdate라는 새 부분 엔터티를 만들어야 합니다.이제 TourUpdate 개체로 업데이트를 호출하면 endAddress가 업데이트되고 startAddress 값은 동일하게 유지됩니다.이것은 API의 새 원격 값으로 DB를 업데이트하지만 로컬 앱 데이터는 테이블에 그대로 두는 DAO의 insertOrUpdate 메서드 사용 사례에 적합합니다.
방법 1과 같은 일부 필드(전부가 아님)를 업데이트하는 방법을 알고 싶습니다(ID = 1).
사용하다@Query
방법 2에서 했던 것처럼.
내 경우에는 너무 긴 쿼리입니다. 왜냐하면 내 엔티티에 많은 필드가 있기 때문입니다.
그런 다음 더 작은 개체를 만듭니다.또는 필드를 개별적으로 업데이트하지 않고 데이터베이스와 더 거친 상호작용을 수행합니다.
IOW, 방 자체에는 당신이 원하는 것을 할 수 있는 어떤 것도 없습니다.
업데이트 2020-09-15: Room은 이제 부분 엔티티 지원을 제공하여 이 시나리오에 도움이 될 수 있습니다.자세한 내용은 이 답변을 참조하십시오.
사용해 볼 수 있지만 성능이 조금 더 나빠질 수 있습니다.
@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)
}
메모 클래스
@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)
업데이트할 특정 모델의 기본 키가 필요합니다.예:
private fun update(Name: String?, Brand: String?) {
val deviceEntity = remoteDao?.getRemoteId(Id)
if (deviceEntity == null)
remoteDao?.insertDevice(DeviceEntity(DeviceModel = DeviceName, DeviceBrand = DeviceBrand))
else
DeviceDao?.updateDevice(DeviceEntity(deviceEntity.id,remoteDeviceModel = DeviceName, DeviceBrand = DeviceBrand))
}
이 기능에서는 데이터베이스에 특정 항목이 있는지 확인하고 있습니다. 만약 존재한다면 id인 기본 키를 여기로 당겨서 업데이트 기능을 수행합니다.
레코드 가져오기 및 업데이트는 다음과 같습니다.
@Query("SELECT * FROM ${DeviceDatabase.DEVICE_TABLE_NAME} WHERE ${DeviceDatabase.COLUMN_DEVICE_ID} = :DeviceId LIMIT 1")
fun getRemoteDeviceId(DeviceId: String?): DeviceEntity
@Update(onConflict = OnConflictStrategy.REPLACE)
fun updatDevice(item: DeviceEntity): Int
URI를 사용하여 데이터베이스의 행을 ID별로 업데이트할 수 있습니다.
Tour tourEntity = new Tour();
tourEntity.end_address = "some adress";
tourEntity.start_address= "some adress";
//tourEntity..... other fields
tourEntity.id = ContentUris.parseId(Uri.parse("content://" + BuildConfig.APPLICATION_ID + File.separator + id));
//get your updatemethod with abstract func in your database class (or with another way, wich you use in project)
int tourDaoUpdate = getInstance(context).tour().update(tourEntity);
또한 업데이트 방법 OnConflictStrategy에 추가해야 합니다.
@Update(onConflict = OnConflictStrategy.REPLACE)
int updateTour(Tour tour);
특정 사용자 ID "x"에 대한 사용자 정보를 업데이트해야 하는 경우,
- 생성자에서 데이터베이스를 초기화하고 viewModel과 DAO 사이의 중재자 역할을 하는 dbManager 클래스를 만들어야 합니다.
View Model은 데이터베이스에 액세스하기 위해 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);
그런 다음 userId가 1122이고 userName이 "xyz"이며 "zyx"로 변경되어야 한다고 가정할 때, 이러한 방법으로 사용자 항목을 업데이트하십시오.
ID 1122의 userItem 사용자 개체 가져오기
User user = new user(); if(user.getUserId() == 1122){ user.setuserName("zyx"); userViewModel.updateUser(user); }
이것은 원시 코드입니다. 도움이 되길 바랍니다.
해피 코딩
언급URL : https://stackoverflow.com/questions/45789325/update-some-specific-field-of-an-entity-in-android-room
'sourcecode' 카테고리의 다른 글
AJAX를 통해 어레이를 mvc Action에 전달 (0) | 2023.08.07 |
---|---|
jQuery에서 processData를 false로 설정하면 AJAX 요청이 중단됨 (0) | 2023.08.07 |
장면 위임자와 앱 위임자의 차이점 (0) | 2023.08.07 |
JavaScript를 사용하여 세션을 만드는 방법은 무엇입니까? (0) | 2023.08.07 |
Moodle 3.6의 질문 뱅크에서 임의 질문을 추가하는 동안 코딩 오류가 발생했습니다. (0) | 2023.08.07 |