代码之家  ›  专栏  ›  技术社区  ›  portfoliobuilder

无法使用@PrimaryKey(autoGenerate=true)进行更新

  •  1
  • portfoliobuilder  · 技术社区  · 6 年前

    我正在使用Room,发现将主键设置为“自动生成”有问题,

    如果执行插入操作,然后再执行更新操作,则这些操作生成的键会有所不同,因此,我的数据不会得到更新。

    @Entity(tableName = "test_table")
    public class TestEntity {
    
        @PrimaryKey(autoGenerate = true)
        private int uid;
    
        @ColumnInfo(name = "expiration_date_access_token")
        private String expirationDateAccessToken;
    
    
        /**
         * Getter for retrieving primary key
         *
         * @return Primary key
         */
        public int getUid() {
            return uid;
        }
    
        /**
         * Setter for setting primary key
         *
         * @param uid Primary key
         */
        public void setUid(int uid) {
            this.uid = uid;
        }
    
        /**
         * Getter for retrieving expiration date of access token
         *
         * @return Expiration date of access token
         */
        public String getExpirationDateAccessToken() {
            return expirationDateAccessToken;
        }
    
        /**
         * Setter for setting expiration date of access token
         *
         * @param expirationDateAccessToken Expiration date of access token
         */
        public void setExpirationDateAccessToken(String expirationDateAccessToken) {
            this.expirationDateAccessToken = expirationDateAccessToken;
        }
    }
    

    下面是一个例子

    @Dao
    public interface TestDao {
    
        @Query("SELECT * FROM test_table")
        List<TestEntity> getAll();
    
        @Query("DELETE FROM test_table")
        void deleteAll();
    
        @Insert
        void insert(TestEntity testEntity);
    
        @Delete
        void delete(TestEntity testEntity);
    
        @Update
        void update(TestEntity testEntity);
    }
    

    @Database(entities = {TestEntity.class}, version = 1, exportSchema = false)
    public abstract class AppDatabase extends RoomDatabase {
    
        private static final String DATABASE_NAME = "room.test.db";
        private static AppDatabase APP_DATABASE_INSTANCE;
    
        public abstract TestDao testDao();
    
        public static AppDatabase getAppdatabase(@NonNull Context context) {
            if (FrameworkUtils.checkIfNull(APP_DATABASE_INSTANCE)) {
                APP_DATABASE_INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                        AppDatabase.class, DATABASE_NAME).build();
            }
            return APP_DATABASE_INSTANCE;
        }
    
        /**
         * Method is used to destroy database instance
         */
        public static void destroy() {
            APP_DATABASE_INSTANCE = null;
        }
    }
    

    我已经将我的LiveData连接到了我的存储库,然而,出于以下过于简单的原因,我也执行了相同的操作。

    Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    // update database tables
                   TestEntity testEntity = new TestEntity();
                   // if I uncomment setting uid, which is the hardcoded primary key
                   // value, the update will happen. If I do not include this, and 
                   // just try to update my data, a new primary key is generated and
                   // the old data does not get updated.
    
                   // testEntity.setUid(1); 
                   testEntity.setExpirationDateAccessToken("12345");
                   AppDatabase.getAppdatabase(context).testDao().update(testEntity);
    
                }
            });
    

        @PrimaryKey(autoGenerate = true)
        private int uid = 1; <---- works with any hardcoded int value
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   dglozano    6 年前

    您创建了一个 TestEntity 然后告诉Room将其保存在数据库中。此时,房间将为其分配一个自动生成的主键。如果你想更新这个特定的 测试性 测试性

    因此,您必须知道要更新的实体的id。第一次保存时,如何判断分配给它的id?你可以做你的 @Insert

    @Insert
    Long insert(TestEntity testEntity);
    

        2
  •  1
  •   Community CDub    4 年前

    我的问题是,使用@PrimaryKey(autoGenerate=true)的模式是什么??

    我是否必须始终检索id,然后在每次更新时将其传入?

    如果参数已经存在(通过主键检查),则该方法的实现将更新其在数据库中的参数。如果它们不存在,此选项将不会更改数据库。

    一定有更好的办法。有什么建议吗?

    • 这取决于你的要求。 若我并没有错的话,我猜你们一直试图在表中只保存一行。

    @查询(“更新测试表,其中1=1”)

    受保护的抽象int更新(TestEntity te);

    另一条路。但在这里你需要设置 uid 一些硬编码的整数。