【问题标题】:Android Room: One database with multiple tablesAndroid Room:一个数据库多表
【发布时间】:2019-08-13 07:37:24
【问题描述】:

我的应用程序有两个单独的表,一个称为用户,另一个称为密​​码。

用户:

@Entity(tableName = "users")
public class Users {
   // some setters and getters here
}

密码:

@Entity(tableName = "passwords")
public class Passwords {
   // some setters and getters here
}

这就是我访问数据库的方式:

usersdb = Room.databaseBuilder(this, Users.class,"mymaindb")
          .allowMainThreadQueries()
          .build();

// Then later in some other activity when I need to use passwords table

passwords = Room.databaseBuilder(this, passwords.class,"mymaindb")
          .allowMainThreadQueries()
          .build();

我遇到的问题是,在全新安装后,当我访问密码时,我无法访问用户,反之亦然。

我收到以下错误:

原因:java.lang.IllegalStateException: Room 无法验证 数据的完整性。看起来您已更改架构但忘记更新 版本号。您可以通过增加版本来简单地解决这个问题 号码。

但是当我尝试使用两个单独的数据库(如 passwords_db 和 users_db 而不是 mymaindb)时,它完全可以正常工作。

那么有没有一种方法可以在一个数据库下拥有多个表?如果是这样,那我做错了什么?提前致谢!

【问题讨论】:

  • 您获得了一个包含一个表的数据库版本。然后你更新它,Room 要求你增加数据库的版本。是这样吗? Room 正在尝试帮助您“Room 无法验证数据完整性。您似乎更改了架构但忘记更新版本号。”.

标签: java android android-room


【解决方案1】:

我认为你完全错了,Room.databaseBuilder 应该只调用一次来设置数据库,并且在该数据库类中,你将构建多个表。例如:

Room.databaseBuilder(this, MyRoomDb.class, "mymaindb")
                .allowMainThreadQueries()
                .build()

你的MyRoomDb 应该是这样的

@Database(
        entities = {
            Users.class,
            Passwords.class
        },
        version = VERSION
)
public abstract class MyRoomDb extends RoomDatabase {
...
}

【讨论】:

  • 你是对的,谢谢!现在我有一个数据库类和数据访问对象,它工作得很好。
  • 很好,很高兴我能帮上忙 :)
  • RoomDB 是否支持 dropAllTables() 和 createAllTables()? stackoverflow.com/questions/62405921/…
【解决方案2】:

你有几个变种来解决这个问题:

  • 重新添加表但增加数据库版本;

    @Database(entities={Users.class, Passwords.class}, version = 2)

  • 清理应用程序设置并构建新数据库;

只需清理应用程序缓存并尝试重新创建数据库。

【讨论】:

    【解决方案3】:

    就像添加一个实体表一样简单。只需使用 "," 添加另一个表名。并且将添加另一个表。

    @Database(entities = [TableUser::class, TableRecord::class], version = 1)
    
    abstract class MyDatabase : RoomDatabase() {
        abstract fun myDao(): MyDao
    }
    

    【讨论】:

    • 也许你应该解释一下你的答案。
    【解决方案4】:

    如果您不想更改代码,您可以简单地卸载并再次安装该应用程序。但这会删除您保存在数据库中的数据。

    【讨论】:

      【解决方案5】:

      这是另一种方法,您可以通过为所有表使用一个 RoomDB 类来获得所需内容:

      @Database(entities = {Users.class, Passwords.class}, version = 1, exportSchema = false)
      public abstract class MyDatabase extends RoomDatabase {
      private static MyDatabase INSTANCE;
      
          public abstract UsersDAO usersDAO();
          public abstract PasswordsDAO passwordsDAO();
      
          public static MyDatabase getDatabase(Context context) {
              if (INSTANCE == null) {
                  INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                          MyDatabase.class, "mydatabase")
                          .build();
              }
              return INSTANCE;
          }
      }
      

      您的实体将如下所示:

      @Entity(tableName = "user_table")
      public class User {
      
          @PrimaryKey(autoGenerate = true)
          private long id;
          private String username;
          private String email;
      
          .............//Constructor goes here
      
          .............//Getters and Setters go here
      
      }
      

      DAO 如下所示:

      @Dao
      public interface UsersDAO {
      
          @Query("SELECT * FROM user_table")
          List<User> getAll();
      
      }
      

      然后你会像这样获取数据:

      AsyncTask.execute(() -> {               
          MyDatabase.getDatabase(getApplicationContext()).usersDAO().getAll();
      });
      

      【讨论】:

        猜你喜欢
        • 2019-05-24
        • 2012-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-10
        • 1970-01-01
        • 2022-12-08
        • 1970-01-01
        相关资源
        最近更新 更多