Can Android Room manage multiple databases and create databases from a template database?(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可以管理多个数据库并从模板数据库创建数据库吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!