我正在为我的新项目使用android房间持久性库。
我想更新一些表的字段。
我在我的Dao
-
// Method 1:
@Dao
public interface TourDao {
@Update
int updateTour(Tour 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
}
答案 0 :(得分:38)
我想知道如何更新某些字段(并非所有字段),例如方法1,其中id = 1
使用@Query
,就像在方法2中一样。
在我的情况下,查询太长了,因为我的实体中有很多字段
然后有更小的实体。或者,不要单独更新字段,而是与数据库进行更粗粒度的交互。
IOW,房间本身没有什么可以做你想要的。
答案 1 :(得分:38)
<!-- 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, intid);
/**
* 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 :(得分:32)
从Room 2.2.0到2019年10月发布,您可以指定目标实体进行更新。然后,如果update参数不同,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值保持不变。对于我在DAO中使用insertOrUpdate方法的用例来说,这非常适合我,该方法用API中的新远程值更新数据库,但将本地应用程序数据保留在表中。
答案 3 :(得分:3)
我认为您不需要仅更新某些特定字段。 只需更新整个数据即可。
@更新查询
基本上是给定查询。无需重新查询。
@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)
答案 4 :(得分:2)
也许您可以尝试一下,但是性能会稍差一些(或更多):
@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);
}
}
答案 5 :(得分:0)
我们需要您要更新的特定模型的主键。 例如:
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为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
答案 6 :(得分:0)
您可以使用 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);
答案 7 :(得分:-1)
在尝试解决我自己的类似问题后,我已将 @PrimaryKey(autoGenerate = true)
更改为 int UUID
,但找不到如何编写迁移,因此我更改了表名,这很简单修复,如果您使用个人/小型应用程序就可以了
答案 8 :(得分:-2)
如果您需要更新特定用户ID“x”的用户信息,
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”。
获取id为1122的userItem用户对象
User user = new user(); if(user.getUserId() == 1122){ user.setuserName("zyx"); userViewModel.updateUser(user); }
这是一个原始代码,希望它可以帮到你。
快乐编码