android left join query with room

眉间皱痕 提交于 2020-03-22 08:12:29

问题


I am trying to change my sqlite database with room library. I am little confuse with left join query.

I have implemented it with sqlite, but don't know how can I achieve same withh room?

Here is my table creation:

first table: Notification

db.execSQL("CREATE TABLE IF NOT EXISTS $TABLE_NAME ($COLUMN_ID INTEGER PRIMARY KEY, $ICON TEXT, $TITLE INTEGER," +
                " $DATE INTEGER, $TYPE INTEGER,$URL TEXT, $MESSAGE INTEGER, FOREIGN KEY($TITLE) REFERENCES ${TableNotificationsTrans.getTableName(this)}(id)," +
                "FOREIGN KEY($MESSAGE) REFERENCES ${TableNotificationsTrans.getTableName(this)}(id))")

second table: Notification_Trans

db.execSQL("CREATE TABLE IF NOT EXISTS $TABLE_NAME ($COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, $COLUMN_EN TEXT, $COLUMN_GU TEXT, $COLUMN_HI TEXT)")

What I am doing is I am storing notification in notification table but its name and description will be stored with specific language, in notification_trans.

Query to achieve

DatabaseHelper.database!!.rawQuery("SELECT A.$COLUMN_ID, A.$ICON, N.${language.toLowerCase()} $TITLE, A.$DATE, A.$TYPE, A.$URL, M.${language.toLowerCase()} $MESSAGE FROM $TABLE_NAME A LEFT JOIN NotificationsTrans N ON A.$TITLE = N.id LEFT JOIN NotificationsTrans M ON A.$MESSAGE = M.id ORDER BY $DATE DESC LIMIT $pageNum*10, 10", null)

Question

How can I achieve same with room?

Edit

My application is multi-language application, where I am getting notification title with specific language, like Hindi or Gujarati. I am storing notification details in notification table, while title in notification_trans.

NotificationTrans have column with id, english, hindi, gujarati.

When user asked for gujarati, I am retriving notification title from notificationTrans's column gujarati.

I am able do so, in sqlite.

But now I want it with Room


回答1:


First You have to make the model classes for both, You may have already declared them , You just need to make a few changes if they already exists.

   @Entity
public class Notification {
    @PrimaryKey
    int id;
    String icon;
    @ForeignKey(entity = Notification_Trans.class, parentColumns = "col_id", childColumns = "id")
    String title;
    int date;
    int type;
    String url;
    int msg;

}

    @Entity
public class Notification_Trans {
    @PrimaryKey(autoGenerate = true)
    int col_id;
    String column_en;
    String column_gu;
    String column_hi;

This makes for your POJO, I couldn't understand your Foreign key constraints, so Pardon me for that, you can make changes as you see fit. You can Declare your DAO as per this` @Dao

public interface DAO {

    @Query("SELECT note.id, note.title, note.description, category.name as categoryName " +
            "FROM note " +
            "LEFT JOIN category ON note.category_id = category.id")
    List getCategoryNotes();

}
`

I haven't made changes in the query, which I found at Link here. As your query was a complex one, But, it'll give you an Idea about how to do that., After this, You just need to access your Dao interface from your Database class object, which will handle the creation & all other things room, like this one below`

@Database(entities = {Notification.class, NotificationTrans.class}, version = 3)
public abstract class AppDatabase extends RoomDatabase {

    private static AppDatabase instance;

    public static AppDatabase getAppDatabase(Context context) {
        if (instance == null) {
            instance =
                    Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "database_name")
                            // allow queries on the main thread.
                            // Don't do this on a real app! See PersistenceBasicSample for an example.
                            //.allowMainThreadQueries()
                            .fallbackToDestructiveMigration()
                            .build();
        }
        return instance;
    }

    public static void destroyInstance() {

        instance = null;
    }

    public abstract Dao notificationDao();

It helps creating a separate class for Database, & keeping track of object from it. & you can access your data with AppDatabase.getAppDatabase(context).notificationDao().yourQueryMethodName();

You may require to refer to this to understand the relations between room, & implement your requirement,

EDIT 1: Here's how your DAO should look like ,`

@Insert
void insert(Notifications object);

//This will insert a single Item

 @Insert
 void insertAll(Notifications... objects);

While this can enter a list of Data,

You can call this methods with your Database object, likeAppDatabase.getAppDatabase(context).notificationDao().yourQueryMethodName() here instead of yourQueryMethod(), if you call insert() & pass the object you need to store in the database, It'll do it,

For E.g.db.parcelDao().insert(parcel); this is how I insert Data in my ParcelDao, db is Database object, & parcel is the object of data need to be stored. One more thing, you can't call this method on main thread, so you may need to use Handler or AsyncTask for the purpose, Sorry I forgot to mention that. Have a look at Room Training at Android Developers for implementation of basic functionality of room



来源:https://stackoverflow.com/questions/47863265/android-left-join-query-with-room

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!