gpt4 book ai didi

android - 如何在 Room 中动态创建新表?

转载 作者:行者123 更新时间:2023-12-04 04:23:21 45 4
gpt4 key购买 nike

请帮帮我。
在我的应用程序中,用户可以通过按下按钮来创建新的数据库表。用户还可以稍后访问此表以接收来自它们的数据。
目前我通过 dataBaseHelper 类使用了旧的 SQLite,所以我可以

public static void createTable(String tableName) {
databaseHelper.getWritableDatabase().execSQL("CREATE TABLE IF NOT EXISTS [" + tableName + "] (...columns)");
}


工作完成了;

现在我想在我的应用程序中使用 Room 库而不是 DataBaseHelper。
我正在查看这个 DAO 接口(interface),它严格绑定(bind)到特定的预定义表,并且不知道该怎么做。
有办法吗?

最佳答案

Is there a way?



但是 动态添加的表可能必须通过 SupportSQLiteDatabase 实例(这是 Room 的 SQLiteDatabase 等价物)通过传统(pre-room)方法使用。

如此有效,您正在击败使用 Room 的一些核心原因。 ,例如面向对象的方法和样板代码的减少。

例子

下面的简单示例创建并填充(如果是新的)一个房间生成/管理的表,然后动态创建和填充(如果是新的)另一个表 但是 通过 SupportSQLiteDatabase 实例在房间的 OO 侧之外。最后,所有数据都从表中提取到 Cursor 中,并转储数据(以证明概念)。

该应用程序运行两次,以表明非房间表的存在不会导致房间检测到更改的架构和由此产生的异常。
  • 需要注意的是,上述没有考虑动态添加表的存储/获取等可变数量的动态表的管理,这样会使事情变得更加复杂。

  • 代码是: -

    BaseEntity.java
    @Entity(tableName = "base")
    public class BaseEntity {

    public static final String BASETABLE_NAME = "base";
    public static final String BASETABLE_COL_ID = BaseColumns._ID;
    public static final String BASETABLE_COL_VALUE = "value";
    public static final String BASETABLE_NAME_PLACEHOLDER = ":tablename:";
    public static final String BASETABLE_CREATE_SQL = "CREATE TABLE IF NOT EXISTS "
    + BASETABLE_NAME_PLACEHOLDER +
    "(" +
    BASETABLE_COL_ID + " INTEGER PRIMARY KEY," +
    BASETABLE_COL_VALUE + " TEXT)";
    @PrimaryKey
    @ColumnInfo(name = BASETABLE_COL_ID)
    Long id;
    @ColumnInfo(name = BASETABLE_COL_VALUE)
    String value;

    public BaseEntity() {}

    @Ignore
    public BaseEntity(String value) {
    this.value = value;
    }

    public Long getId() {
    return id;
    }

    public void setId(Long id) {
    this.id = id;
    }

    public String getValue() {
    return value;
    }

    public void setValue(String value) {
    this.value = value;
    }

    @Ignore
    public static Long insertRow(SupportSQLiteDatabase sdb, String tableName, String value) {
    ContentValues cv = new ContentValues();
    cv.put(BASETABLE_COL_VALUE,value);
    return sdb.insert(tableName, OnConflictStrategy.IGNORE,cv);
    }

    @Ignore
    public static int getTableRowCount(SupportSQLiteDatabase sdb,String tableName) {
    int rv = 0;
    Cursor csr = sdb.query("SELECT count() FROM " + tableName,null);
    if (csr.moveToFirst()) {
    rv = csr.getInt(0);
    }
    csr.close();
    return rv;
    }
    }
  • 可以看出这是房间代码和非房间代码的混合

  • BaseEntityDao.java
    @Dao
    interface BaseEntityDao {

    @Insert
    long insertRow(BaseEntity baseEntity);

    @Query("INSERT INTO base (value) VALUES(:the_value)")
    void insertRow(String the_value);

    @Query("SELECT count() FROM base")
    Integer getRowCount();

    }
  • Room 注释处理器要求 SQLite 标识符(表名、列名)保持原样,它们不能是变量,因此这些只能用于访问 Room 定义的表(因此需要等效项(在此示例中是静态定义的)在 BaseEntity 类中))。

  • 数据库.java
    @androidx.room.Database(version = 1,entities = {BaseEntity.class})
    public abstract class Database extends RoomDatabase {

    public abstract BaseEntityDao baseEntityDao();
    }

    MainActivity.java
    public class MainActivity extends AppCompatActivity {

    Database mDB;
    BaseEntityDao mDao;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mDB = Room.databaseBuilder(this,Database.class,"basedb")
    .allowMainThreadQueries()
    .build();
    mDao = mDB.baseEntityDao();
    addSomeDataViaRoom();
    String dynamicTableName = "testing";
    addTable(dynamicTableName);
    addSomeDataOutsideOfRoom(dynamicTableName);
    SupportSQLiteDatabase sdb = mDB.getOpenHelper().getWritableDatabase();
    Cursor csr = sdb.query("SELECT * FROM " + BaseEntity.BASETABLE_NAME);
    DatabaseUtils.dumpCursor(csr);
    csr = sdb.query("SELECT * FROM " + dynamicTableName);
    DatabaseUtils.dumpCursor(csr);
    mDB.close();
    }

    private boolean addTable(String tableName) {

    SupportSQLiteDatabase sdb = mDB.getOpenHelper().getWritableDatabase();
    try {
    sdb.execSQL(BaseEntity.BASETABLE_CREATE_SQL.replace(BaseEntity.BASETABLE_NAME_PLACEHOLDER, tableName));
    } catch (SQLiteException e) {
    return false;
    }
    return true;
    }

    private void addSomeDataViaRoom() {
    if (mDao.getRowCount() > 0) return;
    mDao.insertRow("A");
    mDao.insertRow("B");
    mDao.insertRow("C");
    }

    private void addSomeDataOutsideOfRoom(String tableName) {
    SupportSQLiteDatabase sdb = mDB.getOpenHelper().getWritableDatabase();
    if (BaseEntity.getTableRowCount(sdb,tableName) > 0) return;
    BaseEntity.insertRow(sdb,tableName,"X");
    BaseEntity.insertRow(sdb,tableName,"Y");
    BaseEntity.insertRow(sdb,tableName,"Z");
    }
    }

    结果(第二轮)
    2019-10-26 08:04:28.650 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@5322d6
    2019-10-26 08:04:28.651 I/System.out: 0 {
    2019-10-26 08:04:28.651 I/System.out: _id=1
    2019-10-26 08:04:28.651 I/System.out: value=A
    2019-10-26 08:04:28.651 I/System.out: }
    2019-10-26 08:04:28.651 I/System.out: 1 {
    2019-10-26 08:04:28.651 I/System.out: _id=2
    2019-10-26 08:04:28.651 I/System.out: value=B
    2019-10-26 08:04:28.651 I/System.out: }
    2019-10-26 08:04:28.651 I/System.out: 2 {
    2019-10-26 08:04:28.651 I/System.out: _id=3
    2019-10-26 08:04:28.651 I/System.out: value=C
    2019-10-26 08:04:28.651 I/System.out: }
    2019-10-26 08:04:28.651 I/System.out: <<<<<
    2019-10-26 08:04:28.651 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@f873957
    2019-10-26 08:04:28.652 I/System.out: 0 {
    2019-10-26 08:04:28.652 I/System.out: _id=1
    2019-10-26 08:04:28.652 I/System.out: value=X
    2019-10-26 08:04:28.652 I/System.out: }
    2019-10-26 08:04:28.652 I/System.out: 1 {
    2019-10-26 08:04:28.652 I/System.out: _id=2
    2019-10-26 08:04:28.652 I/System.out: value=Y
    2019-10-26 08:04:28.652 I/System.out: }
    2019-10-26 08:04:28.652 I/System.out: 2 {
    2019-10-26 08:04:28.652 I/System.out: _id=3
    2019-10-26 08:04:28.652 I/System.out: value=Z
    2019-10-26 08:04:28.652 I/System.out: }
    2019-10-26 08:04:28.652 I/System.out: <<<<<

    关于android - 如何在 Room 中动态创建新表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58556803/

    45 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com