[英]How to write an efficient JPQL query that returns list of linked records in a table?
這是我的后端JPA(ORM)結構:
MessageObject.java
messageId
messageName
relatedMessageId // maps to NEXT message in chain
假設消息名稱中有一些內容表明它是鏈中我應該收到的第一條消息(即messageName為“ Create Message”)。
如何編寫JPQL查詢,該查詢將基於名稱為“ Create Message”的消息按順序返回消息,並根據初始結果中的referencedId值返回下一個消息? 是否有一種更有效的方法來執行流操作,或者我的數據模型結構中存在缺陷?
這不是JPQL問題,而是數據庫設計問題。 不同的數據庫會有所不同,但通常關系數據庫沒有基於遞歸父級進行選擇的簡便方法。
有幾種方法可以解決此問題:
------------------------------------------------------------------
| messageId | messageName | relatedMessageId | rootId | sequence |
------------------------------------------------------------------
| 1 | create | null | 1 | 1 |
| 2 | process | 1 | 1 | 2 |
| 3 | ship | 2 | 1 | 3 |
------------------------------------------------------------------
使用這樣的表,您可以輕松獲取所有創建消息“ where relatedMessageId IS null”。 如果您只需要使用rootId和序列來全部選擇它們,則需要按順序排列鏈中的所有消息。
----------------------------------------------------------------
| messageId | messageName | relatedMessageId | path |
----------------------------------------------------------------
| 1 | create | null | 000>001 |
| 2 | process | 1 | 000>001>002 |
| 3 | ship | 2 | 000>001>003 |
----------------------------------------------------------------
這種方法有點古怪且難以維護,但在速度上有一些好處。 這個想法是在varchar字段中的每個記錄中保留id的路徑。 有了它,您可以選擇“ where path like LIKE'000>%'ORDER BY path”,它將按順序在樹狀列表中選擇所有記錄。 要獲得單個序列,只需將like查詢更改為“ where path LIKE'000> 001>%'ORDER BY path”。 同樣,這種方法很古怪且難以正確維護路徑,但是由於您可以選擇單個查詢而不是多個查詢來選擇所有子級,因此它可以在以后獲得回報。
對...有多種選擇。 我在這里說一個。
我了解您有一個具有messageId和relatedMessageId列的“郵件”表。 您的表將與自身建立自相關關系,即relatedMessageId是messageId的前導鍵。
您的實體看起來像這樣...
@Entity
public class Transaction implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer messageId;
@OneToMany(mappedBy = "relatedMessage")
private List<Message> relatedMessages = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "relatedMessageId")
private Message parentMessage;
// constructors, aux methods, getter and setters
現在,您的JQL看起來像...
select m from Message m where m.parentMessage IS NULL
這將帶來所有重要信息。 由此您可以...
List<Message> parentMessages = messageRepoInstance.findParentMessages();
for(Message message : parentMessages) {
List<Message> relatedMessages = message.getRelatedMessages();
}
抱歉,這全是我的想法,但我相信我設法通過了這個想法。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.