我正在为新项目使用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
}
如何更新表中的列表。 实际上,我已经通过TypeConverter在Table中插入了列表。 但是在进行更新时无法正常工作。 如果遇到任何此类问题,请提出建议。
@ AmanGupta-ShOoTeR对于上述评论,您有任何解决方案吗?
我的图书馆Kripton Persistence Library的工作原理与该Room库非常相似。 如果您想了解我如何使用Kripton解决此问题,请访问abubusoft.com/wp/2019/10/02/
@ AmanGupta-ShOoTeR我在使用@Query更新时遇到了此类问题。 然后我使用@Insert(onConflict = OnConflictStrategy.REPLACE)通过创建具有相同主键值而不是update的对象来工作
根据SQLite更新文档:
@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 getOrderList();
@Query("SELECT * FROM orders")
LiveData> getOrderLiveList();
@Query("SELECT * FROM orders WHERE order_id =:orderId")
LiveData 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);
}
您能再解释一下吗?
对于问题实体,DAO方法将如下所示:@Query(" UPDATE Tour SET endAddress =:end_address,startAdress =:start_address WHERE id =:tid)int updateTour(long tid,String end_address,String start_address);
我的意思是在您的解决方案中:)最好让它在那里供其他用户查看
哦,我认为这很明显。立即修复。
I want to know how can I update some field(not all) like method 1 where id = 1
像在方法2中一样,使用@Query。
is too long query in my case because I have many field in my entity
然后有较小的实体。或者,不要单独更新字段,而是与数据库进行更粗粒度的交互。
IOW,房间本身没有任何东西可以满足您的需求。
@CommonsWare,您好:您能帮我更新房间中自定义对象的类型转换列的列吗?您可能要在这里查看问题:stackoverflow.com/questions/52662832/
是否可以在不传递任何参数的情况下更新表?我的意思是交换一个布尔值。
@VishnuTB:如果您可以创建执行所需操作的SQL语句,则应该可以将其与@Query一起使用。
@CommonsWare知道了。我想获取一组布尔值为true的行。但Room arch不允许我传递true / false作为参数。代替true =1,false=0 SELECT * FROM note_table WHERE isNoteArchived == 0
Room 2.2.0-alpha01(developer.android.com/jetpack/androidx/releases/)为@Update引入了新参数,可用于设置目标实体。这样应该可以进行部分更新。
也许您可以尝试一下,但是性能会稍差一些(或更多):
@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);
}
}
如果您需要更新特定用户ID" x"的用户信息,
您需要创建一个dbManager类,该类将在其构造函数中初始化数据库,并充当viewModel和DAO之间的介体,并且还充当。
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 {
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);
}
这是原始代码,希望对您有所帮助。
快乐编码
您确实在视图模型中执行数据库操作?天哪,没有... :(只是查看型号名称就应该打你