Android - Multiple database one project

2020-02-26 12:49发布

问题:

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.