I am newbie to the Android X Room Database. Earlier I used Sqlitehelper class to access the sqlite databases and then migrated to room. The question is , when I insert data into Room database table it stores for that moment and when I restart the app the data is gone. I want to have multiple tables in a single database.
DAO :
@androidx.room.Dao
public interface ItineraryDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(ItineraryData model);
@Update
void update(ItineraryData model);
@Delete
void delete(ItineraryData model);
@Query("DELETE FROM "+ CONSTANTS.ITINERARY_TABLE)
void deleteAllItinerary();
@Query("SELECT * FROM "+CONSTANTS.ITINERARY_TABLE+" ORDER BY Date ASC")
LiveData<List<ItineraryData>> getAllItinerary();
Database:
@Database(entities = {ItineraryData.class},version = 1,exportSchema = false)
public abstract class ItineraryDatabase extends RoomDatabase {
private static ItineraryDatabase instance;
public abstract ItineraryDao Dao();
public static synchronized ItineraryDatabase getInstance(Context mCon){
if (instance == null) {
instance =
Room.databaseBuilder(mCon.getApplicationContext(),
ItineraryDatabase.class, CONSTANTS.ITINERARY_TABLE)
.fallbackToDestructiveMigration()
.addCallback(roomCallback)
.build();
}
return instance;
}
private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
new PopulateDbAsyncTask(instance).execute();
}
};
private static class PopulateDbAsyncTask extends AsyncTask<Void, Void, Void> {
PopulateDbAsyncTask(ItineraryDatabase instance) {
ItineraryDao dao = instance.Dao();
}
@Override
protected Void doInBackground(Void... voids) {
return null;
}
The above is the code I used is every table to generate table with different Dao's . As I need to create the tablets in a single database i used same CONSTANTS.ITINERARY_TABLE for all of them. If I use differnt names in CONSTANTS.ITINERARY_TABLE this works fine. But it creates different databases.
How can I create multiple tables in a single database without loosing data on restart. I went thorugh some earlier posts. But they suggest to use different database names.
Thank you
How can I create multiple tables in a single database without loosing data on restart.
You define multiple tables by specifying multiple @Entity
annotated classes in the entities parameter of the @Database
annotation.
That is how you tell Room what tables will be created.
Where you use ItineraryDatabase.class, CONSTANTS.ITINERARY_TABLE
, this is telling Room that the database (i.e. the file name) will be named as per CONSTANTS.ITINERARY_TABLE
.
I suspect that you want the same table layout/schema but multiple tables (possibly itself not a good idea as each table has overheads when a single column could indicate the equivalent of the row belonging to a specific set of data).
Additional (DEMO)
Considering the comment:-
I want to have different table with different table schema's in a single database file. I have seperate entity classes for them. Do i need to have getinstance for each table in this single class ( which extends with roomdatabase) ? One Database Class with multiple getinstance?
and also the presumption of a single schema (not that it matters much if not, simpler if not). Then consider the following code that is based very much on your code.
ItineraryData (used as a model for two tables, so not @Entity annotated - can be ignored if different schemas);-
class ItineraryData {
@PrimaryKey
Long id=null;
long date=System.currentTimeMillis() / 1000;
@NonNull
String otherColumn;
}
CONSTANTS :-
class CONSTANTS {
static final String ITINERARY_TABLE = "it01";
static final String ITINERARY_TABLE_2 = "it02";
}
ItineraryTable01 (bit of a cheat as schema grabbed from ItineraryData) :-
@Entity(tableName = CONSTANTS.ITINERARY_TABLE)
class ItineraryTable01 extends ItineraryData {
}
ItineraryTable02 (cheat again):-
@Entity(tableName = CONSTANTS.ITINERARY_TABLE_2)
class ItineraryTable02 extends ItineraryData {
}
ItineraryDao
@Dao
public interface ItineraryDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(ItineraryTable01 model);
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(ItineraryTable02 model);
@Update
void update(ItineraryTable01 model);
@Update
void update(ItineraryTable02 model);
@Delete
void delete(ItineraryTable01 model);
@Delete
void delete(ItineraryTable02 model);
@Query("DELETE FROM " + CONSTANTS.ITINERARY_TABLE)
void deleteAllItineraryTable01();
@Query("DELETE FROM " + CONSTANTS.ITINERARY_TABLE_2)
void deleteAllItineraryTable02();
@Query("SELECT * FROM " + CONSTANTS.ITINERARY_TABLE + " ORDER BY Date ASC")
/*LiveData<*/List<ItineraryTable01>/*>*/ getAllItineraryTable01();
@Query("SELECT * FROM " + CONSTANTS.ITINERARY_TABLE + " ORDER BY Date ASC")
/*LiveData<*/List<ItineraryTable02>/*>*/ getAllItineraryTable02();
}
ItineraryDatabase
@Database(entities = { ItineraryTable01.class,ItineraryTable02.class/*ItineraryData.class*/} ,version = 1,exportSchema = false)
public abstract class ItineraryDatabase extends RoomDatabase {
private static ItineraryDatabase instance;
public abstract ItineraryDao Dao();
public static synchronized ItineraryDatabase getInstance(Context mCon) {
if (instance == null) {
instance =
Room.databaseBuilder(mCon.getApplicationContext(),
ItineraryDatabase.class, CONSTANTS.ITINERARY_TABLE)
.allowMainThreadQueries() /*<<<<<<<<<< Added for convenience brevity of demo */
.fallbackToDestructiveMigration()
.addCallback(roomCallback)
.build();
}
return instance;
}
private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
new PopulateDbAsyncTask(instance).execute();
}
};
private static class PopulateDbAsyncTask extends AsyncTask<Void, Void, Void> {
PopulateDbAsyncTask(ItineraryDatabase instance) {
ItineraryDao dao = instance.Dao();
}
@Override
protected Void doInBackground(Void... voids) {
return null;
}
}
}
Finally to demo some code in an activity :-
public class MainActivity extends AppCompatActivity {
ItineraryDatabase db;
ItineraryDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ItineraryTable01 it01 = new ItineraryTable01();
ItineraryTable02 it02 = new ItineraryTable02();
it01.otherColumn = "blah01";
it02.otherColumn = "blah02";
db = ItineraryDatabase.getInstance(this);
dao = db.Dao();
/* Not until following code is executed is the database actually opened */
dao.insert(it01); /* Inserts into table01 */
dao.insert(it02); /* Inserts into table02 */
}
}
Results
When first run
Using App Inspection:-
and
Run again (aka rerun)
and