Eylen
Eylen

Reputation: 2677

How to add new tables in library with Room?

I am planning to start the migration of an existing app to Architecture Components and one of my doubts is how should I organize the new code.

I have some tables that are added in a personal library that's only included in some flavors, how can those Entities and DAOs be added to the main application if the database class exists on the main application?

Should I add another database class to the library? If so, wouldn't it collide with existing Database class in the main application?

I have been searching, but haven't been able to find any example or tutorial...

Edit to clarify Database question

From the docs I understand that in the Database abstract class, you have to tell which Entities exist and also create access methods for the DAOs. How could this be done if there are entities in the library?

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

Upvotes: 6

Views: 18377

Answers (5)

Zhar
Zhar

Reputation: 3540

The Room persistence library supports incremental migrations with the Migration classes to address this need. Each Migration subclass defines a migration path between a startVersion and an endVersion.

So, the right answer (and the correct way because you should not use fallbackToDestructiveMigration) is :

Add your new table as a java class

@Entity(tableName = "Fruit")
public class Fruit implements Parcelable {
        
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(index = true, name = "id")
        private int id;
    
        @ColumnInfo(name = "name")
        private String name;
    
    ...
    
    }

Update your database version AND add your entity in entities declaration (you add the class definition to tells room should take the class into consideration) and add your dao getter

@Database(version = 2, entities = {User.class, Fruit.class})
abstract class AppDatabase extends RoomDatabase {
     
     abstract public UserDao userDao();
     
     abstract public FruitDao fruitDao();
}

Add migration sql script with your database builder like this

 public static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
                    + "`name` TEXT, PRIMARY KEY(`id`))");
        }
    };
    
    Room.databaseBuilder(getApplicationContext(), MyDb.class, "database-name")
            .addMigrations(MIGRATION_1_2).build();

Source : https://developer.android.com/training/data-storage/room/migrating-db-versions

Upvotes: 6

rumbur4k
rumbur4k

Reputation: 3

With Kotlin you can use an array literal. Add your entities like in example code and higher database version:

    Database(
entities = [Product::class, Category::class], 
version = version + 1, 
exportSchema = false)

Upvotes: 0

selvabharathi s
selvabharathi s

Reputation: 157

for a short cut.

to add a new table to room database.

1) create a new table - you can do by creating a java class with annotation @Entity(tableName = "user_data") - inside this table you will create all the column/fields you want in your table.

2) create a new DAO (data access object) - as we know we have a model class (java). we hold it like an object, to retrive, so, create a interface with annotation @Dao - as this will have all the SQL query statement and act as a intermediate(interface) between the Database, and your commands.

3) adding your new table to the data base - be carefull here, if you do it wrong, you may loose the data, or your app might crash.

1st add the table class you created to the entities attribute

@Database(entities = {TableOne.class,UserData.class},version = 1)

2nd note we don't increase the version number from 1 to 2, will explain you bellow you we did like this.

3rd add this abstract method, so that it can be overridden at every place as you need.

public abstract UserDataDAO getUserDataDao();

4th this would be same as you had before with the single table.

private static final String DB_Name = "myDatabase";
private static DataBase instance;
public static synchronized DataBase getInstance(Context context)
{
    if(instance == null)
    {
        instance = 
  Room.databaseBuilder(context.getApplicationContext(),DataBase.class,DB_Name)
                .allowMainThreadQueries()
                .fallbackToDestructiveMigration()
                .build();
    }
    return instance;
}

5th after adding the new table your code will look like

@Database(entities = {TableOne.class,UserData.class},version = 1)
public abstract class DataBase extends RoomDatabase {
private static final String DB_Name = "myDatabase";
private static DataBase instance;

public abstract tableOne getTableOneDao();
public abstract UserDataDAO getUserDataDao();



public static synchronized DataBase getInstance(Context context)
{
    if(instance == null)
    {
        instance = 
         Room.databaseBuilder(context.getApplicationContext(),DataBase.class,DB_Name)
                .allowMainThreadQueries()
                .fallbackToDestructiveMigration()
                .build();
    }
    return instance;
}

}

6th now uninstall the app, if you had already installed it in your device, since we did not migrate and change, that's why i not increased the version.

7th now when you install your app freshly it will be handling with two table.

8th by doing in this strategy is not appreciable, since your data is lost.

9th you need to migrate the app change the version number by increasing, then write a static method which tells about the migration.

please look for this blog where you find awesome migration technique with clear explanation.

check here

Upvotes: 0

Santanu Sur
Santanu Sur

Reputation: 11487

@Database(version = 1, entities = {User.class, Book.class})
abstract class AppDatabase extends RoomDatabase {
     // BookDao is a class annotated with @Dao.
     abstract public BookDao bookDao();
     // UserDao is a class annotated with @Dao.
     abstract public UserDao userDao();
     // UserBookDao is a class annotated with @Dao.
     abstract public UserBookDao userBookDao();
}

If you want to update the Room database and add table...just add another entity then update the version if you add another entity like Movies table.. do something like this

@Database(version = 2, entities = {User.class, Book.class, Movies.class})
abstract class AppDatabase extends RoomDatabase {
     // BookDao is a class annotated with @Dao.
     abstract public BookDao bookDao();
     // UserDao is a class annotated with @Dao.
     abstract public UserDao userDao();
     // UserBookDao is a class annotated with @Dao.
     abstract public UserBookDao userBookDao();
     // MoviesDao is a class annotated with @Dao.
     abstract public MoviesDao moviesDao();
     // UserMoviesDao is a class annotated with @Dao.
     abstract public UserMoviesDao userMoviesDao();
}

for reference you can check ... this

Upvotes: 9

Foroogh Varmazyar
Foroogh Varmazyar

Reputation: 1585

with Kotlin :

   @Database(version = 1, entities = [User::class, Book::class])
        abstract class AppDatabase : RoomDatabase() {
        //UserDao is a class annotated with @Dao
            abstract fun userDao(): UserDao
        // BookDao is a class annotated with @Dao
            abstract fun bookDao(): BookDao   
        }

Upvotes: 0

Related Questions