Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Multiple database one project

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

like image 500
KostasC Avatar asked Sep 05 '18 14:09

KostasC


People also ask

Can a project have multiple databases?

Generally, if one project consumes multiple databases, it is because it must consume different, often legacy sources of information that originated outside of this particular project. This is most common in Enterprise environments.

Can we use multiple databases for a single application?

If you can work with single database, working with multiple is no different. You will need a connection string for each database. There rest is, as they say it, history.

Can an app have two databases?

Multiple database technologies can be used with monolithic applications, and can even seem more natural in a microservices environment, where each service would have its own database. This approach, however, is not bulletproof. Far from it, actually.

Can you create multiple databases in parallel?

A parallel server can consolidate several databases to simplify administrative tasks.


2 Answers

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

like image 200
Gregorio Palamà Avatar answered Sep 27 '22 16:09

Gregorio Palamà


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.

like image 20
Deˣ Avatar answered Sep 27 '22 15:09

Deˣ