Xác định mối quan hệ một-nhiều giữa các thực thể Phòng cho mô hình Trò chuyện


8

Tôi bắt đầu sử dụng cơ sở dữ liệu phòng và trải qua một số tài liệu để tạo các thực thể phòng. Đây là những mối quan hệ của tôi. Một kênh trò chuyện có thể có nhiều cuộc trò chuyện. Vì vậy, điều này đi như mối quan hệ một-nhiều. Do đó tôi đã tạo ra các thực thể như dưới đây.

Thực thể kênh

@Entity(primaryKeys = ["channelId"])
@TypeConverters(TypeConverters::class)
data class Channel(
    @field:SerializedName("channelId")
    val channelId: String,
    @field:SerializedName("channelName")
    val channelName: String,
    @field:SerializedName("createdBy")
    val creationTs: String,
    @field:SerializedName("creationTs")
    val createdBy: String,
    @field:SerializedName("members")
    val members: List<String>,
    @field:SerializedName("favMembers")
    val favMembers: List<String>
) {
  // Does not show up in the response but set in post processing.
  var isOneToOneChat: Boolean = false
  var isChatBot: Boolean = false
}

Thực thể hội thoại

@Entity(primaryKeys = ["msgId"],
    foreignKeys = [
        ForeignKey(entity = Channel::class,
                parentColumns = arrayOf("channelId"),
                childColumns = arrayOf("msgId"),
                onUpdate = CASCADE,
                onDelete = CASCADE
        )
    ])
@TypeConverters(TypeConverters::class)
data class Conversation(

    @field:SerializedName("msgId")
    val msgId: String,
    @field:SerializedName("employeeID")
    val employeeID: String,
    @field:SerializedName("channelId")
    val channelId: String,
    @field:SerializedName("channelName")
    val channelName: String,
    @field:SerializedName("sender")
    val sender: String,
    @field:SerializedName("sentAt")
    val sentAt: String,
    @field:SerializedName("senderName")
    val senderName: String,
    @field:SerializedName("status")
    val status: String,
    @field:SerializedName("msgType")
    val msgType: String,
    @field:SerializedName("type")
    val panicType: String?,
    @field:SerializedName("message")
    val message: List<Message>,
    @field:SerializedName("deliveredTo")
    val delivered: List<Delivered>?,
    @field:SerializedName("readBy")
    val read: List<Read>?

) {

data class Message(
        @field:SerializedName("txt")
        val txt: String,
        @field:SerializedName("lang")
        val lang: String,
        @field:SerializedName("trans")
        val trans: String
)

data class Delivered(
        @field:SerializedName("employeeID")
        val employeeID: String,
        @field:SerializedName("date")
        val date: String
)

data class Read(
        @field:SerializedName("employeeID")
        val employeeID: String,
        @field:SerializedName("date")
        val date: String
)

    // Does not show up in the response but set in post processing.
    var isHeaderView: Boolean = false
}

Bây giờ bạn có thể thấy Hội thoại thuộc về Kênh . Khi người dùng nhìn thấy một danh sách các kênh, tôi cần hiển thị một số thuộc tính của Cuộc hội thoại cuối cùng trong mục danh sách. Câu hỏi của tôi là, liệu tôi chỉ cần khai báo mối quan hệ như trên hay tôi nên chứa đối tượng Converstion trong lớp Kênh? Những cách khác mà tôi có thể xử lý nó là gì? Bởi vì UI cần có được cuộc trò chuyện gần đây nhất xảy ra cùng với thời gian, trạng thái, v.v. trong mỗi mục của danh sách kênh khi người dùng cuộn. Vì vậy, không nên có bất kỳ độ trễ nào trong UI vì điều này khi tôi truy vấn.

Và làm thế nào tôi có thể có đối tượng Converstaion gần đây trong đối tượng Kênh?

Câu trả lời:


1

Tôi đề nghị tạo một lớp khác (không phải trong DB, chỉ để hiển thị trong UI) như thế này:

data class LastConversationInChannel(
    val channelId: String,
    val channelName: String,
    val creationTs: String,
    val createdBy: String,
    val msgId: String,
    val employeeID: String,
    val sender: String,
    val sentAt: String,
    val senderName: String
    .
    .
    .
)

Nhận cuộc hội thoại cuối cùng trong mỗi Kênh bằng truy vấn này:

 SELECT Channel.*
 ,IFNULL(LastConversation.msgId,'') msgId
 ,IFNULL(LastConversation.sender,'') sender
 ,IFNULL(LastConversation.employeeID,'') employeeID
 ,IFNULL(LastConversation.sentAt,'') sentAt
 ,IFNULL(LastConversation.senderName,'') senderName
 from Channel left join 
 (SELECT * from Conversation a  
 WHERE a.msgId IN ( SELECT b.msgId  FROM Conversation AS b 
                    WHERE a.channelId = b.channelId 
                    ORDER BY b.sentAt DESC  LIMIT 1 )) as LastConversation
 on Channel.channelId = LastConversation.channelId

sau đó sử dụng nó trong dao của bạn như thế này:

 @Query(" SELECT Channel.*\n" +
            " ,IFNULL(LastConversation.msgId,'') msgId\n" +
            " ,IFNULL(LastConversation.sender,'') sender\n" +
            " ,IFNULL(LastConversation.employeeID,'') employeeID\n" +
            " ,IFNULL(LastConversation.sentAt,'') sentAt\n" +
            " ,IFNULL(LastConversation.senderName,'') senderName\n" +
            " from Channel left join \n" +
            " (SELECT * from Conversation a  \n" +
            " WHERE a.msgId IN ( SELECT b.msgId  FROM Conversation AS b \n" +
            "                    WHERE a.channelId = b.channelId \n" +
            "                    ORDER BY b.sentAt DESC  LIMIT 1 )) as LastConversation\n" +
            " on Channel.channelId = LastConversation.channelId")
    fun getLastConversationInChannel(): LiveData<List<LastConversationInChannel>>

Là đủ nếu tôi chỉ khai báo mối quan hệ như trên hoặc tôi nên chứa đối tượng Converstion trong lớp Kênh?

Bạn không nên chứa Hội thoại trong lớp Kênh, vì Phòng sẽ tạo một số cột cho nó trong bảng Hội thoại.


0

Bạn có thể có một LastConversationcái Conversation objectbên trong Chanel. Bạn phải cập nhật thông tin này mỗi lần cập nhật LastConversation bằng cách sửa đổi bảng Chanel từ lớp Room. (Không mất quá nhiều hiệu năng để cập nhật db). Bằng cách thực hiện sắp xếp cho danh sách Chanel (Có thể so sánh). Cập nhật giao diện người dùng của bạn sẽ được mát mẻ. Và logic của bạn từ UI hoặc ViewModel đơn giản hơn. Tôi cũng đã làm theo cách này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.