DocumentReference Dữ liệu mùa xuân MongoDB

Tôi gặp vấn đề tương tự với kotlin, tôi nghĩ nó liên quan đến cách dữ liệu mùa xuân khởi tạo tham chiếu, trong trường hợp của tôi

không làm việc

@Document("test")
data class Test(
  @Id
  val id: ObjectId? = null,
  val name: String,
  @CreatedDate
  val createdAt: Instant = Instant.MIN,
  @CreatedBy
  val createdById: ObjectId = ObjectId(),
  @ReadOnlyProperty
  @DocumentReference(lookup = "{ '_id' : ?#{#self.createdById} }")
  val createdBy: User? = null
)

đang làm việc

@Document("test")
data class Test(
  @Id
  val id: ObjectId? = null,
  val name: String,
  @CreatedDate
  val createdAt: Instant = Instant.MIN,
  @CreatedBy
  val createdById: ObjectId = ObjectId(),      
) {
  @ReadOnlyProperty
  @DocumentReference(lookup = "{ '_id' : ?#{#self.createdById} }")
  var createdBy: User? = null
}

bạn có thể thử với lớp java thông thường thay vì bản ghi

Trong hướng dẫn này, chúng ta sẽ xem xét chú thích @DBRef của Spring Data MongoDB. Chúng tôi sẽ kết nối các tài liệu MongoDB bằng chú thích này. Ngoài ra, chúng ta sẽ thấy các loại tham chiếu cơ sở dữ liệu MongoDB và so sánh chúng.

2. Tham khảo cơ sở dữ liệu thủ công MongoDB

Loại đầu tiên mà chúng ta thảo luận được gọi là tham chiếu thủ công. Trong MongoDB, mọi tài liệu đều phải có trường id. Do đó, chúng ta có thể tin tưởng vào việc sử dụng nó và kết nối các tài liệu với nó

Khi sử dụng tham chiếu thủ công, chúng tôi lưu trữ _id của tài liệu được tham chiếu trong một tài liệu khác.  

Sau này, khi chúng tôi truy vấn dữ liệu từ bộ sưu tập đầu tiên, chúng tôi có thể bắt đầu truy vấn thứ hai để tìm nạp các tài liệu được tham chiếu

3. Dữ liệu mùa xuân MongoDB @DBRef Chú thích

DBRef tương tự như tham chiếu thủ công theo nghĩa là chúng cũng chứa _id của tài liệu được tham chiếu. Tuy nhiên, chúng chứa bộ sưu tập của tài liệu được tham chiếu trong trường $ref và tùy chọn cả cơ sở dữ liệu của nó trong trường $db

Ưu điểm của điều này so với tham chiếu thủ công là nó làm rõ bộ sưu tập nào chúng tôi đang tham chiếu

4. Cài đặt ứng dụng

4. 1. phụ thuộc

Đầu tiên, chúng ta cần thêm các phụ thuộc cần thiết để sử dụng MongoDB với Spring Boot

Hãy thêm spring-boot-starter-data-mongodb vào pom của chúng ta. xml


    org.springframework.boot
    spring-boot-starter-data-mongodb

4. 2. Cấu hình

Bây giờ, chúng tôi thiết lập kết nối bằng cách thêm cấu hình sau vào ứng dụng. tệp thuộc tính

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=person_database

Hãy chạy ứng dụng để kiểm tra xem chúng ta có thể kết nối với cơ sở dữ liệu không. Chúng ta sẽ thấy một thông báo tương tự như thế này trong nhật ký

Opened connection [connectionId{localValue:2, serverValue:37}] to localhost:27017

Điều này có nghĩa là ứng dụng có thể kết nối thành công với MongoDB

4. 3. bộ sưu tập

Trong MongoDB, chúng tôi sử dụng các bộ sưu tập để lưu trữ các tài liệu riêng lẻ. Chúng là bản sao của các bảng trong cơ sở dữ liệu quan hệ

Trong ví dụ này, chúng tôi sẽ làm việc với ba loại dữ liệu khác nhau. Người, Chó và Mèo. Chúng tôi sẽ kết nối mọi người với thú cưng của họ

Hãy tạo các bộ sưu tập trong cơ sở dữ liệu với một số dữ liệu. Chúng tôi có thể sử dụng Mongo Express cho việc này, nhưng bất kỳ công cụ nào khác cũng sẽ hoạt động

Đầu tiên, hãy tạo một cơ sở dữ liệu có tên person_database và tạo hai bộ sưu tập bên trong cơ sở dữ liệu đó có tên là Dog và Cat. Chúng tôi sẽ chèn một tài liệu vào mỗi một. Để đơn giản hóa, cả hai sẽ chỉ có một tài sản. tên thú cưng

Hãy chèn tài liệu này vào bộ sưu tập Dog

{
    _id: ObjectID("622112d71f9dac417b84227d"), 
    name: "Max"
}

Sau đó, hãy chèn tài liệu này vào bộ sưu tập Cat .

{
    _id: ObjectID("622112781f9dac417b84227b"),
    name: "Loki"
}

Bây giờ, hãy tạo bộ sưu tập Person và chèn một tài liệu vào đó.

{
    _id: ObjectId(),
    name: "Bob",
    pets: [
        {
          "$ref": "Cat",
          "$id": "622112781f9dac417b84227b",
          "$db": ""
        },    
        {
          "$ref": "Dog",
          "$id": "622112d71f9dac417b84227d",
          "$db": ""
        }
    ]
}

Chúng tôi cung cấp các vật nuôi như một mảng. Các mục của mảng cần tuân theo một định dạng cụ thể để có thể sử dụng chúng dưới dạng DBRefs. Chúng tôi cần cung cấp tên của bộ sưu tập trong thuộc tính $ref. Trong trường hợp này, đó là Mèo và Chó. Sau đó, chúng tôi bao gồm ID của các tài liệu được tham chiếu. Cuối cùng, chúng ta có thể tùy chọn bao gồm tên cơ sở dữ liệu trong thuộc tính $db nếu chúng ta muốn tham chiếu các bộ sưu tập từ một cơ sở dữ liệu khác

5. Sử dụng Chú thích @DBRef

Chúng ta có thể ánh xạ các bộ sưu tập đã tạo trước đó sang các lớp Java, tương tự như những gì chúng ta sẽ làm khi làm việc với cơ sở dữ liệu quan hệ

Để đơn giản hóa, chúng ta sẽ không tạo các lớp riêng cho kiểu dữ liệu Dog và Cat. Thay vào đó, chúng ta sẽ sử dụng lớp Pet chứa ID và tên

________số 8

Bây giờ, chúng ta sẽ tạo lớp Người và bao gồm một liên kết với Thú cưng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . class via @DBRef:

@Document(collection = "Person")
public class Person {

    @Id
    private String id;
    
    private String name;

    @DBRef
    private List pets;

    @Override 
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", pets=" + pets + "]";
    }

    // standard getters and setters
}

Tiếp theo, hãy tạo một kho lưu trữ đơn giản để có thể truy vấn dữ liệu

@Document("test")
data class Test(
  @Id
  val id: ObjectId? = null,
  val name: String,
  @CreatedDate
  val createdAt: Instant = Instant.MIN,
  @CreatedBy
  val createdById: ObjectId = ObjectId(),      
) {
  @ReadOnlyProperty
  @DocumentReference(lookup = "{ '_id' : ?#{#self.createdById} }")
  var createdBy: User? = null
}
0

Chúng tôi sẽ kiểm tra mọi thứ bằng cách tạo một ApplicationRunner thực thi truy vấn MongoDB khi chúng tôi khởi động ứng dụng. Hãy ghi đè phương thức run() và đặt một câu lệnh log để chúng ta có thể xem nội dung của bộ sưu tập Person

@Document("test")
data class Test(
  @Id
  val id: ObjectId? = null,
  val name: String,
  @CreatedDate
  val createdAt: Instant = Instant.MIN,
  @CreatedBy
  val createdById: ObjectId = ObjectId(),      
) {
  @ReadOnlyProperty
  @DocumentReference(lookup = "{ '_id' : ?#{#self.createdById} }")
  var createdBy: User? = null
}
1

Điều này tạo ra một đầu ra nhật ký tương tự như thế này bởi vì chúng ta đã ghi đè phương thức toString() trong các lớp thực thể của mình

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=person_database
0

Điều này có nghĩa là chúng tôi đã đọc và tham gia thành công tài liệu từ các bộ sưu tập khác nhau.

5. 1. Tham khảo một cơ sở dữ liệu khác

Chú thích @DBRef chấp nhận hai tham số. Một trong số đó là tham số db, có thể được sử dụng để tham chiếu các tài liệu trong cơ sở dữ liệu khác

Đây là tùy chọn, có nghĩa là ứng dụng sẽ tìm các tài liệu được tham chiếu trong cùng một cơ sở dữ liệu nếu chúng tôi không cung cấp giá trị này

Trong trường hợp của chúng tôi, nếu Mèo hoặc Chó cư trú trong một cơ sở dữ liệu khác có tên pet_database, thì chúng tôi cần thay đổi chú thích thành điều này. @DBRef(db = “pet_database”)

5. 2. tải chậm

Tham số khác được chú thích chấp nhận được gọi là lazy. Đây là một giá trị boolean xác định xem các tài liệu được tham chiếu có nên được tải một cách lười biếng hay không

Theo mặc định, nó là sai, có nghĩa là các tham chiếu sẽ được tải háo hức khi chúng tôi truy vấn thực thể chính. Nếu chúng tôi bật tính năng này, các tài liệu được tham chiếu sẽ không được tải cho đến khi chúng được truy cập trước

6. Sự kết luận

Trong bài viết này, chúng tôi đã so sánh các tham chiếu thủ công MongoDB với Spring Data MongoDB @DBRef. Chúng tôi đã tạo ba bộ sưu tập và kết nối chúng với chú thích này. Chúng tôi đã tạo một ứng dụng Spring Boot để truy vấn các bộ sưu tập này bằng MongoRepository và hiển thị các tài liệu liên quan