当前位置: 首页 > 知识库问答 >
问题:

自动更新新插入的房间实体中的主键

秦新立
2023-03-14

在Room中添加新创建的对象时,自动生成主键,新创建的对象将保留其未定义的主键。当您需要修改此对象并保留更改时,这证明是不方便的。

让我们举个例子。

因此,让我们创建一个用户,其id是自动生成的。

@Entity()
public class User {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    private int id;

    @ColumnInfo(name = "email")
    private String email;

    public User(String email) {
        this.email = email;
    }

    // Other methods, especially getter and setter for each field

    // …
}

我们有以下Dao:

public class UserDao {
    @Insert
    void insert(User user);

    @Update
    int update(User user);

    // …
}

我们通过以下存储库进行交互:

public class Repository {
    private UserDao userDao;

    public void addUser(User user) {
        userDao.insert(user);
    }

    public void update(User user) {
        userDao.update(user);
    }

    // …
}

所以,现在如果我们这样做,user将不会被更新,因为User.id将保持在0并且Update注释仅在主键已经存在的情况下更新行。

Repository r = new Repository();
User user = new User("me@my.email");
r.addUser(user);
user.setEmail("new@user.email");

为了解决这个问题,我们可以将RepositoryaddUser方法更改为在插入后更新id。这个问题给了我以下的想法:

public class Repository {
    private UserDao userDao;

    public void addUser(User user) {
        long rowid = userDao.insert(user);
        user.setId(userDao.getIdFromRowid(rowid));
    }

    // …
}

使用此Dao(请注意,insert返回一个long,而不是void):

public class UserDao {
    @Insert
    long insert(User user);

    @Update
    int update(User user);

    @Query("SELECT id FROM user WHERE ROWID = :rowid")
    int getIdFromRowid(long rowid);

    // …
}

在Android Jetpack范例中,这是一个可接受的解决方案吗?你看到什么陷阱了吗?

共有1个答案

丌官昊天
2023-03-14

您建议的解决方案是可以接受的,您可以从Room DB获取插入的id,然后将其设置为对象引用。这样就可以执行更新和删除操作。另一个认为你可以资源管理器和使用的是选择查询上的LiveData,它会在回调中更新数据,每当它在房间数据库中发生变化时。但是,这取决于你的逻辑。示例:

@Query("SELECT * from test_tbl")
 LiveData<List<Model>> getTestData();  
 类似资料:
  • 我用这个房间已经有一段时间了。我来自mysql的背景,您必须检查查询和其他内容的值。在room中,我发现这有点复杂,因为到目前为止,我可以将dao insert查询声明为void,或者只要返回rowId,如果返回long,我就必须编写一个侦听器来通知UI成功/失败。我的问题是,这是否必要?我是否需要insert/updates/deletes的返回值,或者这些查询是否保证成功?

  • 我正在使用room将前台位置服务获取的数据与an活动进行通信。服务连接到viewmodel并插入数据,但是活动不会从viewmodel接收更新的LiveData,但是它能够在开始时获取一个LiveData>对象,并且在重新启动应用程序时具有准确的大小。我错过了什么?我需要将新数据插入到数据库中,所以如果我确实需要在服务和postValue中使用MutableLiveData,那么我将不得不每次发布

  • 我在房间使用关系中添加了一对多关系。我引用这篇文章是为了编写以下房间关系代码。 这篇文章讲述了如何从数据库中读取值,但将实体存储到数据库中会导致用户ID为空,这意味着这两个表之间没有关系。 我不确定在具有用户ID值的情况下,将用户和宠物列表插入数据库的理想方法是什么。 1)用户实体: 2) 宠物实体: 3)用户带宠物POJO: 现在,为了从DB中获取记录,我们使用以下DAO: 编辑 我已创建此问题

  • 我遇到了一个问题,我找不到任何关于Android空间和自动生成主键的文档。 我有一个实体类,看起来有点像这样: 当我手动设置id时,这是正常的,但是当我不设置主键时,我得到一个关于主键为空的错误。看着自动生成的文件,我看不到它会自动增加主键的任何地方。 所以我想我的问题是:你能用setter自动生成私有成员的主键吗,或者我需要在setter中手动自动生成我的键吗?

  • 我是Android的新手,需要一些帮助。 我的问题是我到底什么时候调用命令,以及room如何知道哪一行发生了更改?我不想更新到整个表。 如果我应该用另一种方式解释,请告诉我。

  • 我想这可能是一个新手问题,但我仍然想知道一些答案。 假设存在实体:医院和医生(多对多)。假设在我的controller类中,我必须获取所有现有的医生和医院,然后在特定的医院雇佣一名医生 它当然不起作用,因为--据我所知--我已经在控制器中获取了所有的医生和医院,然后在hireDoctor方法中,我们打开了传递常规Java对象的trasaction,这些对象不在会话中。 我知道,我可以用一个特殊的身