NoSQL数据库與關聯式數據庫的區別在於允許更複雜的結構,而無需傳統的一對多或一對一關係。相反,NoSQL數據庫利用靈活的類型,如數組或子文檔,在單個文檔內有效存儲相關數據。這種靈活性使開發人員能夠設計符合其應用程序查詢和性能需求的模型。
Jakarta NoSQL是一個簡化與NoSQL數據庫(包括MongoDB)交互的Java框架。它提供注釋來確定數據如何映射和存儲,使開發人員能夠控制嵌入對象是分組還是以平面方式存儲。
在使用MongoDB和Jakarta NoSQL時,一個關鍵考慮因素是如何結構化您的文檔。在平面結構和分組結構之間的選擇將影響數據的存儲、查詢和檢索方式。在本文中,我們使用一個實際示例探索這兩種方法。
Jakarta NoSQL和Product實體
為了理解平面結構和分組結構,讓我們首先介紹Product
實體並看看Jakarta NoSQL注釋是如何工作的:
public class Product {
ObjectIdConverter.class) (
private String id;
private String name;
private Manufacturer manufacturer;
private List<String> tags;
private Set<Category> categories;
Product(String name, Manufacturer manufacturer, List<String> tags, Set<Category> categories) {
this.name = name;
this.manufacturer = manufacturer;
this.tags = tags;
this.categories = categories;
}
public static ProductBuilder builder() {
return new ProductBuilder();
}
}
現在,讓我們探索如何根據Jakarta NoSQL注釋將manufacturer
字段存儲不同。
理解分組結構和平面結構
分組結構
一個分組結構將相關信息組織成文件中的不同對象。這種方法提高了可讀性,並允許更清潔的領域建模實踐。Jakarta NoSQL 通過使用@Embeddable(Embeddable.EmbeddableType.GROUPING)
實現這一點。
例子:
{
"_id": { "$oid": "67b264520abd020ec0eb9a4c" },
"categories": [
{ "name": "Computers", "description": "All computers" },
{ "name": "Electronics", "description": "All electronics" }
],
"manufacturer": {
"address": "One Infinite Loop Cupertino, CA 95014",
"name": "Apple",
"contactNumber": "+1-408-996-1010"
},
"name": "MacBook Pro",
"tags": ["smartphone", "tablet", "laptop"]
}
在這裡,製造商被分組到一個單獨的子對象中,而不是將其屬性放在頂層。
Embeddable.EmbeddableType.GROUPING) (
public record Manufacturer( String name, String address, String contactNumber) {}
扁平結構
一個扁平結構將相關信息嵌入到同一個文件中,直接嵌入列表或嵌套字段。Jakarta NoSQL 通過使用@Embeddable(Embeddable.EmbeddableType.FLAT)
實現這一點。當您希望快速訪問所有細節而無需複雜查詢時,這種方法很有用。
例子:
{
"_id": { "$oid": "67b22d20c921154b0223b27b" },
"address": "One Infinite Loop Cupertino, CA 95014",
"categories": [
{ "name": "Electronics", "description": "All electronics" },
{ "name": "Computers", "description": "All computers" }
],
"contactNumber": "+1-408-996-1010",
"name": "Apple",
"tags": ["smartphone", "tablet", "laptop"]
}
這種方法直接將製造商詳細信息存儲在文件中,而不是將它們分組到獨立字段中。
Embeddable.EmbeddableType.FLAT) (
public record Manufacturer( String name, String address, String contactNumber) {}
Jakarta NoSQL中的例子用法
以下代碼片段演示了 Jakarta NoSQL 如何集成這些結構:
public class App {
public static void main(String[] args) {
var faker = new Faker();
try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
var template = container.select(DocumentTemplate.class).get();
var electronicsCategory = new Category("Electronics", "All electronics");
var computerCategory = new Category("Computers", "All computers");
var tags = List.of("smartphone", "tablet", "laptop");
var manufacturer = new Manufacturer("Apple", "One Infinite Loop Cupertino, CA 95014", "+1-408-996-1010");
Product macBookPro = Product.builder().categories(Set.of(electronicsCategory, computerCategory))
.manufacturer(manufacturer)
.name("MacBook Pro")
.tags(tags)
.build();
Product product = template.insert(macBookPro);
System.out.println("Product saved: " + product);
}
}
}
選擇正確的方法
- 當您需要一個簡單的文檔布局,所有屬性都在同一級時,請使用扁平結構。
- 當將相關數據組織成邏輯子對象以提高可讀性和可維護性時,請使用分組結構。
結論
Jakarta NoSQL 提供了使用 @Embeddable(Embeddable.EmbeddableType)
結構化 MongoDB 文件的彈性。選擇 平面 或 分組 結構取決於您的數據訪問模式和建模偏好。瞭解這些方法可以實現高效的數據庫設計,使查詢更加有效,同時保持域模型的清晰和結構良好。
完整的程式碼,請訪問 GitHub 存儲庫。
視頻
Source:
https://dzone.com/articles/handling-embedded-data-in-nosql-with-java