Обновите определенное поле объекта в комнате Android.

Я использую библиотеку персистентности комнаты 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
}

Ответы

Ответ 1

Я хочу знать, как я могу обновить некоторое поле (не все), как метод 1, где id = 1

Используйте @Query, как и в методе 2.

слишком длинный запрос в моем случае, потому что у меня много полей в моей сущности

Затем имеют меньшие объекты. Или, не обновляйте поля отдельно, а вместо этого выполняйте более грубые взаимодействия с базой данных.

IOW, в Комнате нет ничего, что будет делать то, что вы ищете.

Ответ 2

Согласно Документам обновления 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);
}

Ответ 3

Может быть, вы можете попробовать это, но производительность будет немного хуже (или больше):

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

Ответ 4

Просто создайте отдельный класс, который содержит только те поля, которые вы хотите обновить. Затем скопируйте поля из более крупного класса (который действует как ваш источник) в этот отдельный класс и используйте этот отдельный класс в качестве параметра в вашем обновлении. Используйте @Update, чтобы сделать это.

Ответ 5

Если вам необходимо обновить информацию о пользователе для определенного идентификатора пользователя "x",

  1. вам необходимо создать класс dbManager, который будет инициализировать базу данных в своем конструкторе и действовать как посредник между вашим viewModel и DAO, а также.
  2. ViewModel инициализирует экземпляр 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".

    Получить userItem id 1122 Пользовательский объект

User user = new user();
 if(user.getUserId() == 1122){
   user.setuserName("zyx");
   userViewModel.updateUser(user);
 }

Это сырой код, надеюсь, он вам поможет.

Счастливое кодирование