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
答案 0 :(得分:1)
首先你必须为两者制作模型类,你可能已经声明了它们,如果它们已经存在,你只需做一些改变。
@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;
这使您的POJO,我无法理解您的外键约束,所以请原谅我,您可以根据需要进行更改。 你可以根据这个'声明你的DAO @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();
}
`
我未在Link here找到的查询中进行了更改。由于您的查询很复杂,但是,它会为您提供有关如何执行此操作的建议。 在此之后,您只需要从您的Database类对象访问您的Dao接口,该对象将处理创建&所有其他的东西,如下面的这个`
@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();
它有助于为数据库创建一个单独的类,&跟踪它的对象。
&安培;您可以使用AppDatabase.getAppDatabase(context).notificationDao().yourQueryMethodName();
您可能需要参考this来了解房间与房间之间的关系。实现您的要求,
编辑1: 这就是你的DAO应该是什么样的,“
@Insert
void insert(Notifications object);
//这将插入单个项目
@Insert
void insertAll(Notifications... objects);
虽然这可以输入数据列表,
如果您拨打AppDatabase.getAppDatabase(context).notificationDao().yourQueryMethodName()
&传递你需要存储在数据库中的对象,它会做,
对于例如yourQueryMethod()
这是我在ParcelDao中插入数据的方式,db是数据库对象,& parcel是需要存储的数据对象。还有一件事,你不能在主线程上调用这个方法,所以你可能需要使用Handler或AsyncTask这个目的,抱歉,我忘记提及了。
请查看会议室Training at Android Developers以实现会议室的基本功能
答案 1 :(得分:0)
#1 - 需要创建一个与查询结果匹配的模型类
data class ClientAndCity(
@ColumnInfo(name="id") val id: Long,
@ColumnInfo(name="client_name") val clientName: String?,
@ColumnInfo(name="city_name") val cityName: String?
)
#2 - 在 DAO 中创建查询
@Query("SELECT clients.id, clients.name AS client_name, cities.name AS city_name FROM clients LEFT JOIN cities ON cities.id = clients.city_id WHERE clientes.id = :clientId")
fun getClientAndHisCity(clientId: Long): ClientAndCity?
#3 - 使用你的功能
CoroutineScope(Dispatchers.IO).launch{
val result: ClientAndCity = clientDAO.getClientAndHisCity(clientId)
//do something with it
}