【问题标题】:android left join query with roomandroid左连接查询与房间
【发布时间】:2017-12-18 06:37:48
【问题描述】:

我正在尝试使用房间库更改我的 sqlite 数据库。我对左连接查询有点困惑。

我已经用sqlite实现了,但不知道如何实现相同的空间?

这是我的表创建:

第一个表:通知

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))")

第二个表: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)")

我正在做的是将通知存储在 notification 表中,但其名称和描述将以特定语言存储在 notification_trans 中。

查询实现

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)

问题

How can I achieve same with room?

编辑

我的应用程序是多语言应用程序,我会在其中收到特定语言的通知标题,例如印地语或古吉拉特语。我将通知详细信息存储在 notification 表中,而标题存储在 notification_trans 中。

NotificationTrans 有 id、english、hindi、gujarati 列。

当用户询问古吉拉特语时,我正在从 notificationTrans 的古吉拉特语列中检索通知标题。

我可以这样做,在 sqlite 中。

但现在我想要房间

【问题讨论】:

  • 如果你有一个静态查询,你会在 Room 中使用它,就像在 SQLite 中使用它一样。在您的情况下,您正在使用字符串插值来生成查询,在这种情况下 Room 无法帮助您。

标签: android database android-room kotlin-android-extensions


【解决方案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` @道

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);

虽然这可以输入数据列表,

你可以用你的Database对象调用这个方法,比如这里AppDatabase.getAppDatabase(context).notificationDao().yourQueryMethodName()而不是yourQueryMethod(),如果你调用insert()&传递你需要存储在数据库中的对象,它会做到的,

例如db.parcelDao().insert(parcel); 这就是我在 ParcelDao 中插入数据的方式,db 是数据库对象,parcel 是需要存储的数据对象。还有一件事,你不能在主线程上调用这个方法,所以你可能需要使用 Handler 或 AsyncTask 来达到目的,对不起,我忘了提。 查看 Room Training at Android Developers 实现房间的基本功能

【讨论】:

  • 请给出详细答案..如何插入
  • 让我知道你不明白的地方,我会尝试详细说明那部分
  • 如何在数据库中插入值?
  • 这不会插入到trans表中
  • 你可以为trans表做类似的方法,你只需要为那个类创建一个类似的Dao,更多参考developer.android.com/training/data-storage/room/index.html
【解决方案2】:

#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
}

【讨论】:

    猜你喜欢
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 2021-12-25
    • 2017-06-30
    相关资源
    最近更新 更多