I would like to ask if is possible to have multiple database under one project, with Room Persistence Library? Changing dynamic the selection of the database. Thanks
问题:
回答1:
It is possible. Let's assume you have two sets of entities and two sets of DAOs. You can obtain access to two databases by:
- creating two classes that extends RoomDatabase:
AppDatabase 1:
@Database(entities = {/*... the first set of entities ...*/}, version = 1)
public abstract class AppDatabase1 extends RoomDatabase {
// the first set of DAOs
}
AppDatabase2:
@Database(entities = {/*... the second set of entities ...*/}, version = 1)
public abstract class AppDatabase2 extends RoomDatabase {
// the second set of DAOs
}
- instantiating the two databases:
Note that you'll use two different file names.
AppDatabase db1 = Room.databaseBuilder(getApplicationContext(), AppDatabase1.class, "database1.db").build();
AppDatabase db2 = Room.databaseBuilder(getApplicationContext(), AppDatabase2.class, "database2.db").build();
In this case, you can use both databases, but you won't be able to create queries between them. If you need to attach the two databases, then you should take a look at the link @Anees provided
回答2:
You can reuse the entities and DAO if databases have the same schema and dynamically switch between them (helpful if you want to have a different database file for each user).
Entity class
@Entity
public class User {
@PrimaryKey
@NonNull
public String uid;
@ColumnInfo(name = "first_name")
public String firstName;
@ColumnInfo(name = "last_name")
public String lastName;
}
DAO class
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAll();
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
List<User> loadAllByIds(int[] userIds);
@Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
"last_name LIKE :last LIMIT 1")
User findByName(String first, String last);
@Insert
void insertAll(User... users);
@Delete
void delete(User user);
}
Database class
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
DatabaseClient class
public class DatabaseClient {
private Context mCtx;
private AppDatabase appDatabase;
private static String databaseName;
private static DatabaseClient mInstance;
private DatabaseClient(Context mCtx, String dbName) {
this.mCtx = mCtx;
if(databaseName == null || !databaseName.equalsIgnoreCase(dbName)) {
databaseName = dbName;
}
appDatabase = Room.databaseBuilder(mCtx, AppDatabase.class, databaseName).build();
}
public String getDatabaseName() {
return databaseName;
}
public static synchronized DatabaseClient getInstance(Context mCtx, String dbName) {
if (mInstance == null || databaseName == null || !databaseName.equalsIgnoreCase(dbName)) {
mInstance = new DatabaseClient(mCtx, dbName);
}
return mInstance;
}
public AppDatabase getAppDatabase() {
return appDatabase;
}
}
Now you can query based on a particular database by passing its name in the parameter in my case here let's say myDb
List<User> users = DatabaseClient.getInstance(getApplicationContext(), myDb).getAppDatabase().userDao().getAll()
Remember whenever you perform the first call with a database name, it creates the database file. If a new user arrives and calls to insert its info, it automatically creates a new database file and inserts the info data into it.