Android Room可以管理多个数据库并从模板数据库创建数据库吗? [英] Can Android Room manage multiple databases and create databases from a template database?

查看:23
本文介绍了Android Room可以管理多个数据库并从模板数据库创建数据库吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对以下最佳实践或选项有什么想法、建议或想法?

问题:使用Android Room,在一个Android应用中创建和处理多个数据库的实际方法是什么?

我要做的是:我有一个旨在管理多个研究主题的Android应用。这个想法是用户可以创建特定于主题或研究的数据库,并能够存储关于这些主题的来源、附件和笔记。例如,用户可以拥有专门用于现代音乐史的数据库,关于狩猎史主题的第二个数据库,甚至像微生物学研究那样深入的主题。

我的想法是拥有独立的数据库,而不是存储所有这些数据的一个数据库。特别是因为附件可以很快地存储和占用空间。这些数据库可以在手机/平板电脑应用程序和桌面版本之间共享。正在使用此文件的Java桌面版本。

我所做的&我真的只在这里搜索了一下,用谷歌搜索了一些,但看起来有点模糊。我熟悉并已将更改迁移到数据库,但不确定这是否始终是创建新数据库和重命名等的最佳方式。

这款Android应用程序附带了一个预定义和预弹出的数据库作为演示。这个数据库已经两年没有改变了。因此,这个想法可能是让";template.db";用于创建新数据库并相应地重命名它们。

推荐答案

使用Android Room,在单个Android应用中创建和处理多个数据库的实用方法是什么?

您当然可以处理多个数据库和基于同一架构的多个数据库。

问题是如何确定有哪些数据库可以使用。如果所有数据库都位于相同路径(甚至多个路径)中,则可以使用此选项。另一种方法可以是拥有数据库的数据库。

下面是一个使用数据库的数据库(";MasterDatabase";)并允许访问x个数据库的示例。

因此,首先是MasterDatabase,它有一个简单的表,其中包含一个id列(可以省去)和一个用于数据库名称的列。命名为MasterDatabaseList的表(@Entity)按如下方式命名:-

@Entity(
        indices = { @Index(value = "databaseName", unique = true)
        }
)
class MasterDatabaseList {
    @PrimaryKey
    Long id;
    String databaseName;

    public MasterDatabaseList() {}

    @Ignore
    public MasterDatabaseList(String databaseName) {
        this.databaseName = databaseName;
    }

    public Long getId() {
        return id;
    }

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

    public String getDatabaseName() {
        return databaseName;
    }

    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }
}
  • 请注意databaseName列上的唯一索引

表附带MasterDao@DAO类:-

@Dao
abstract class MasterDao {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    abstract long insert(MasterDatabaseList masterDatabaseList);
    @Query("SELECT * FROM masterdatabaselist")
    abstract List<MasterDatabaseList> getAllDatabases();
}
  • 允许插入或提取行。
  • 重复的数据库将被忽略,因此不会添加。

MasterDatabase是@Database类(将以前的类绑定到数据库),并且包含一个方法,用于获取可从中访问MasterDao的数据库实例:-

@Database(
        entities = {MasterDatabaseList.class},
        version = 1
)
abstract class MasterDatabase extends RoomDatabase {
    abstract MasterDao getMasterDao();

    static volatile MasterDatabase instance = null;

    public static MasterDatabase getInstance(Context context) {
        if (instance == null) {
            instance = Room.databaseBuilder(context,MasterDatabase.class,"master.db")
                    .allowMainThreadQueries()
                    .build();
        }
        return instance;
    }
}
现在模板数据库Base?(用于演示的简单的单表数据库)。首先是表BaseTable@Entity类:-

@Entity
class BaseTable {
    @PrimaryKey
    Long id;
    String mydata;

    public BaseTable(){}

    @Ignore
    public BaseTable(String myData) {
        this.mydata = myData;
    }

    public Long getId() {
        return id;
    }

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

    public String getMydata() {
        return mydata;
    }

    public void setMydata(String mydata) {
        this.mydata = mydata;
    }
}
  • 一个非常简单的表,包含一个id列和一个保存一些字符串数据的列。

附带@DAO类BaseDao:-

@Dao
abstract class BaseDao {
    @Insert
    abstract long insert(BaseTable baseTable);
    @Query("SELECT * FROM basetable")
    abstract List<BaseTable> getAllBaseTables();
    @Update
    abstract int update(BaseTable baseTable);
}
  • 使用非常简单的插入、提取和更新

和之前的@Database类一样BaseDatabase:-

@Database(
        entities = {BaseTable.class},
        version = 1
)
abstract class BaseDatabase extends RoomDatabase {
    abstract BaseDao getBaseDao();

    public static BaseDatabase getInstance(Context context, String databaseName) {
        BaseDatabase instance = null;
        if (databaseName != null) {
            return Room.databaseBuilder(context, BaseDatabase.class, databaseName)
                    .allowMainThreadQueries()
                    .build();
        }
        return instance;
    }
}
  • 请注意数据库名称需要如何传递,这基本上是满足多个数据库的关键。

所有这些都是演示活动。

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "DBINFO";

    MasterDatabase masterDB;
    MasterDao masterDao;

    /* 3 Lists that need to be synchronised index wise */
    /* i.e. each index position should hold the respective name/databaseobject/dao
    /* List of the known databases (their names) */
    List<MasterDatabaseList> masterDatabaseListList = null;
    /* List of the BaseDatabase objects */
    ArrayList<BaseDatabase> baseDatabaseList = new ArrayList<>();
    /* List of the BaseDao's */
    ArrayList<BaseDao> baseDaoList = new ArrayList<>();

    /* The current database */
    int currentBaseIndex = -1; /* Index into the three Lists */
    BaseDatabase currentDB = null;
    BaseDao currentDao = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        masterDB = MasterDatabase.getInstance(this);
        masterDao = masterDB.getMasterDao();
        masterDatabaseListList = masterDao.getAllDatabases();
        // Add default db1  if it does not exist
        if (masterDatabaseListList.size() < 1) {
            addBaseDB("db1");
        }
        buildBaseLists();

        /* Add some data to db1 IF it exists (it should) */
        setCurrentIndexDBandDao("db1");
        if (currentBaseIndex > -1) {
            currentDao.insert(new BaseTable("Blah for db1"));
        }

        /* Add some data to db2 (it will not exist) */
        /* noting that the database will be created if it does not exist */
        setCurrentIndexDBandDao("db2");
        if (currentBaseIndex == -1) {
            addBaseDB("db2");
        }
        if (currentBaseIndex > -1) {
            currentDao.insert(new BaseTable("Blah for db2"));
        }

        /* Extract and Log Data for ALL the BaseDatabase databases i.e. db1 and db2 */
        for(MasterDatabaseList masterdb: masterDao.getAllDatabases()) {
            Log.d(TAG,"Database is " + masterdb.getDatabaseName());
            setCurrentIndexDBandDao(masterdb.databaseName);
            if (currentBaseIndex > -1) {
                for(BaseTable bt: currentDao.getAllBaseTables()) {
                    Log.d(TAG,"Extracted Base Table  row where MyData is" + bt.getMydata());
                }
            }
        }
    }

    /* Add a new Database */
    /* Note that it assumes that it will now be the current */
    /* so the current values are set */
    private void addBaseDB(String baseDBName) {
        masterDao.insert(new MasterDatabaseList(baseDBName));
        buildBaseLists();
        setCurrentIndexDBandDao(baseDBName);
    }

    /* Build/ReBuild the 3 Lists according to the master database */
    /* This could be better managed so as to not rebuild existing database/dao objects */
    private void buildBaseLists() {
        int ix = 0;
        baseDatabaseList.clear();
        baseDaoList.clear();
        masterDatabaseListList = masterDao.getAllDatabases();
        // Loop through the databases defined in the master database adding the database and dao to the respective lists
        for (MasterDatabaseList masterDB: masterDao.getAllDatabases()) {
            BaseDatabase baseDB = BaseDatabase.getInstance(this, masterDB.getDatabaseName());
            baseDatabaseList.add(baseDB);
            baseDaoList.add(baseDB.getBaseDao());
            ix++;
        }
    }

    /* Set the current trio according to the database name that is:*/
    /*  1.the currentBaseIndex for the 3 Lists */
    /*  2. the BaseDatabase object */
    /*  3. the BaseDao */
    /* The index value (currentBaseIndex) is also returned */

    private int setCurrentIndexDBandDao(String baseDBName) {
        currentBaseIndex = getListIndexByBaseDBName(baseDBName);

        if (currentBaseIndex > -1) {
            currentDB = baseDatabaseList.get(currentBaseIndex);
            currentDao = baseDaoList.get(currentBaseIndex);
        }
        return currentBaseIndex;
    }

    /* Get the index according to the database name passed */
    /* note -1 signifies not know/found */
    private int getListIndexByBaseDBName(String baseDBName) {
        masterDatabaseListList = masterDao.getAllDatabases(); // OverKill????
        int rv = -1; // default to not found
        for(int i=0; i < masterDatabaseListList.size();i++) {
            if (masterDatabaseListList.get(i).databaseName.equals(baseDBName)) {
                rv = i;
                break;
            }
        }
        return rv;
    }

    /* Output all rows from the BaseTable for data extracted by the BaseDaos getAllBaseTables */
    private void logBaseData(List<BaseTable> baseTableList) {
        Log.d(TAG,"Current Database Index is " + currentBaseIndex + " DB name is " + masterDatabaseListList.get(currentBaseIndex).getDatabaseName());
        for(BaseTable bt: baseTableList) {
            Log.d(TAG,"	MyData value is " + bt.getMydata());
        }
    }
}

结果

第一次运行上述日志时,日志包含:-

2021-09-16 11:39:30.262 D/DBINFO: Database is db1
2021-09-16 11:39:30.278 D/DBINFO: Extracted Base Table  row where MyData isBlah for db1
2021-09-16 11:39:30.278 D/DBINFO: Database is db2
2021-09-16 11:39:30.284 D/DBINFO: Extracted Base Table  row where MyData isBlah for db2

并通过Android Studio的App Inspector查看数据库:-

对于DB2基表:-

  • 注意以上内容仅用于介绍使用多个数据库的基础知识,这是一种简单化的解释,因此代码保持简短。对于将分发的应用程序来说,这可能是不可接受的。

这篇关于Android Room可以管理多个数据库并从模板数据库创建数据库吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆