Update some specific field of an entity in android Room

前端 未结 7 1586
臣服心动
臣服心动 2020-11-29 16:45

I am using android room persistence library for my new project. I want to update some field of table. I have tried like in my Dao -

// Method 1         


        
相关标签:
7条回答
  • 2020-11-29 17:26

    I want to know how can I update some field(not all) like method 1 where id = 1

    Use @Query, as you did in Method 2.

    is too long query in my case because I have many field in my entity

    Then have smaller entities. Or, do not update fields individually, but instead have more coarse-grained interactions with the database.

    IOW, there is nothing in Room itself that will do what you seek.

    UPDATE 2020-09-15: Room now has partial entity support, which can help with this scenario. See this answer for more.

    0 讨论(0)
  • 2020-11-29 17:26

    We need the primary key of that particular model that you want to update. For example:

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

    In this function, I am checking whether a particular entry exists in the database if exists pull the primary key which is id over here and perform update function.

    This is the for fetching and update records:

    @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
    
    0 讨论(0)
  • 2020-11-29 17:31

    According to 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);
    

    Example:

    Entity:

    @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);
    }
    
    0 讨论(0)
  • 2020-11-29 17:36

    As of Room 2.2.0 released October 2019, you can specify a Target Entity for updates. Then if the update parameter is different, Room will only update the partial entity columns. An example for the OP question will show this a bit more clearly.

    @Update(entity = Tour::class)
    fun update(obj: TourUpdate)
    
    @Entity
    public class TourUpdate {
        @ColumnInfo(name = "id")
        public long id;
        @ColumnInfo(name = "endAddress")
        private String endAddress;
    }
    

    Notice you have to a create a new partial entity called TourUpdate, along with your real Tour entity in the question. Now when you call update with a TourUpdate object, it will update endAddress and leave the startAddress value the same. This works perfect for me for my usecase of an insertOrUpdate method in my DAO that updates the DB with new remote values from the API but leaves the local app data in the table alone.

    0 讨论(0)
  • 2020-11-29 17:47

    If you need to update user information for a specific user ID "x",

    1. you need to create a dbManager class that will initialise the database in its constructor and acts as a mediator between your viewModel and DAO, and also .
    2. The ViewModel will initialize an instance of dbManager to access the database. The code should look like this:

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

      Then just update your user item this way, suppose your userId is 1122 and userName is "xyz" which has to be changed to "zyx".

      Get an userItem of id 1122 User object

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

    This is a raw code, hope it helps you.

    Happy coding

    0 讨论(0)
  • 2020-11-29 17:48

    You could try this, but performance may be worse a little:

    @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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题