帶有 Spring 數據的 MongoDB 組合鍵
一、簡介
在本教程中,我們將在 Spring Data MongoDB 應用程序中創建複合鍵。我們將了解不同的策略以及如何配置它們。
2. 什麼是複合鍵以及何時使用它
複合鍵是文檔中唯一標識它的屬性的組合。使用複合主鍵並不比使用單個自動生成的屬性更好或更差。我們甚至可以將這些方法與唯一索引結合起來。
通常,沒有單一的屬性能夠唯一地標識一個文檔。在這些情況下,我們可以將其留空,MongoDB 將為其“ _id
”屬性生成一個唯一值。或者,我們可以選擇多個屬性,當它們組合時,服務於該目的。在這種情況下,我們必須為我們的 ID 屬性創建一個自定義類來保存所有這些屬性。讓我們看看這是如何工作的。
3. 使用@Id
註解創建複合鍵
@Id
註釋可用於註釋自定義類型的屬性,從而完全控制其生成。 ID 類的唯一要求是我們覆蓋equals()
和hashCode()
並具有默認的無參數構造函數。
在我們的第一個示例中,我們將為活動門票創建一個文檔。它的 ID 將是venue
和date
屬性的組合。讓我們從我們的 ID 類開始:
public class TicketId {
private String venue;
private String date;
// getters and setters
// override hashCode() and equals()
}
由於無參數構造函數是隱式的,而且我們不需要其他構造函數,所以我們不需要編寫它。此外,我們將使用String
日期來簡化示例。接下來,讓我們創建我們的Ticket
類,並使用@Id
註釋我們的TicketId
屬性:
@Document
public class Ticket {
@Id
private TicketId id;
private String event;
// getters and setters
}
對於我們的MongoRepository
,我們可以將TicketId
指定為 ID 類型,這就是所需的全部設置:
public interface TicketRepository extends MongoRepository<Ticket, TicketId> {
}
3.1。測試我們的模型
因此,嘗試兩次插入具有相同 ID 的票證將引發DuplicateKeyException
。我們可以通過測試來檢查:
@Test
public void givenCompositeId_whenDupeInsert_thenExceptionIsThrown() {
TicketId ticketId = new TicketId();
ticketId.setDate("2020-01-01");
ticketId.setVenue("V");
Ticket ticket = new Ticket(ticketId, "Event C");
service.insert(ticket);
assertThrows(DuplicateKeyException.class, () -> {
service.insert(ticket);
});
}
這可以確保我們的密鑰正常工作。
3.2.按 ID 查找
由於我們將TicketId
定義為存儲庫中的 ID 類,我們仍然可以使用默認的findById()
方法。讓我們編寫一個測試來看看它的實際效果:
@Test
public void givenCompositeId_whenSearchingByIdObject_thenFound() {
TicketId ticketId = new TicketId();
ticketId.setDate("2020-01-01");
ticketId.setVenue("Venue B");
service.insert(new Ticket(ticketId, "Event B"));
Optional<Ticket> optionalTicket = ticketRepository.findById(ticketId);
assertThat(optionalTicket.isPresent());
Ticket savedTicket = optionalTicket.get();
assertEquals(savedTicket.getId(), ticketId);
}
當我們想要絕對控制我們的 ID 屬性時,我們應該使用這種方法。同樣,這將確保我們的 ID 對像中的屬性不能被修改。一個缺點是我們丟失了 MongoDB 生成的 ID,可讀性較差。但是,例如,更易於在鏈接中使用。
4. 警告
當使用嵌套對像作為 ID 時,屬性的順序很重要。使用我們的存儲庫時這通常不是問題,因為 Java 對象總是以相同的順序構造的。但是,如果我們更改TicketId
類中字段的順序,我們可以插入另一個具有相同值的文檔。例如,這些對像被認為是不同的:
{
"id": {
"venue":"Venue A",
"date": "2023-05-27"
},
"event": "Event 1"
}
之後,如果我們更改TicketId
中的字段順序,我們將能夠插入相同的值。不會拋出異常:
{
"id": {
"date": "2023-05-27",
"venue":"Venue A"
},
"event": "Event 1"
}
如果我們在Ticket
類的屬性上使用唯一索引而不是 ID 類,則不會發生這種情況。換句話說,它只發生在嵌套對像上。
5. 結論
在本文中,我們看到了為 MongoDB 文檔創建複合鍵的優缺點。以及使用簡單用例實現它們所需的配置。但是,我們還了解到一個需要注意的重要警告。
與往常一樣,源代碼可在 GitHub 上獲得。