MongoDB tự động đóng kết nối

Trong hướng dẫn này, chúng ta sẽ xem các cách khác nhau để định cấu hình kết nối với cơ sở dữ liệu của chúng ta. Chúng tôi sẽ sử dụng Spring Boot và Spring Data MongoDB. Khám phá cấu hình linh hoạt của Spring, chúng tôi sẽ tạo một ứng dụng khác nhau cho từng phương pháp. Kết quả là, chúng tôi sẽ có thể chọn một trong những phù hợp nhất

2. Kiểm tra kết nối của chúng tôi

Trước khi chúng tôi bắt đầu xây dựng các ứng dụng của mình, chúng tôi sẽ tạo một lớp thử nghiệm. Hãy bắt đầu với một vài hằng số chúng ta sẽ sử dụng lại

public class MongoConnectionApplicationLiveTest {
    private static final String HOST = "localhost";
    private static final String PORT = "27017";
    private static final String DB = "baeldung";
    private static final String USER = "admin";
    private static final String PASS = "password";

    // test cases
}

Các thử nghiệm của chúng tôi bao gồm chạy ứng dụng của chúng tôi, sau đó cố gắng chèn một tài liệu vào bộ sưu tập có tên là “các mục”. Sau khi chèn tài liệu của chúng tôi, chúng tôi sẽ nhận được “_id” từ cơ sở dữ liệu của mình và chúng tôi coi thử nghiệm đã thành công. Hãy tạo một phương thức trợ giúp cho điều đó

private void assertInsertSucceeds[ConfigurableApplicationContext context] {
    String name = "A";

    MongoTemplate mongo = context.getBean[MongoTemplate.class];
    Document doc = Document.parse["{\"name\":\"" + name + "\"}"];
    Document inserted = mongo.insert[doc, "items"];

    assertNotNull[inserted.get["_id"]];
    assertEquals[inserted.get["name"], name];
}

Phương thức của chúng tôi nhận ngữ cảnh Spring từ ứng dụng của chúng tôi để chúng tôi có thể truy xuất đối tượng MongoTemplate. Sau đó, chúng tôi xây dựng một tài liệu JSON đơn giản từ một chuỗi có Tài liệu. phân tích cú pháp []

Bằng cách này, chúng ta không cần tạo kho lưu trữ hoặc lớp tài liệu. Sau đó, sau khi chèn, chúng tôi xác nhận các thuộc tính trong tài liệu được chèn của chúng tôi là những gì chúng tôi mong đợi

3. Thiết lập tối thiểu thông qua ứng dụng. tính chất

Ví dụ đầu tiên của chúng tôi là cách phổ biến nhất để định cấu hình kết nối. Chúng tôi chỉ cần cung cấp thông tin cơ sở dữ liệu trong ứng dụng của mình. tính chất

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=baeldung
spring.data.mongodb.username=admin
spring.data.mongodb.password=password

Tất cả các thuộc tính khả dụng nằm trong lớp MongoProperties từ Spring Boot. Chúng ta cũng có thể sử dụng lớp này để kiểm tra các giá trị mặc định. Chúng tôi có thể xác định bất kỳ cấu hình nào trong tệp thuộc tính của mình thông qua các đối số ứng dụng. Chúng ta sẽ thấy nó hoạt động như thế nào trong phần sau

Trong lớp ứng dụng của chúng tôi, chúng tôi không cần bất cứ điều gì đặc biệt để thiết lập và chạy

@SpringBootApplication
public class SpringMongoConnectionViaPropertiesApp {

    public static void main[String.. args] {
        SpringApplication.run[SpringMongoConnectionViaPropertiesApp.class, args];
    }
}

Cấu hình này là tất cả những gì chúng ta cần để kết nối với phiên bản cơ sở dữ liệu của mình. Chú thích @SpringBootApplication bao gồm @EnableAutoConfiguration. Cần quan tâm đến việc phát hiện ra rằng ứng dụng của chúng tôi là một ứng dụng MongoDB dựa trên đường dẫn lớp của chúng tôi

Để kiểm tra, chúng ta có thể sử dụng SpringApplicationBuilder để lấy tham chiếu đến ngữ cảnh ứng dụng. Sau đó, để khẳng định kết nối của chúng tôi là hợp lệ, chúng tôi sử dụng phương thức assertInsertSucceeds đã tạo trước đó

@Test
public void whenPropertiesConfig_thenInsertSucceeds[] {
    SpringApplicationBuilder app = new SpringApplicationBuilder[SpringMongoConnectionViaPropertiesApp.class]
    app.run[];

    assertInsertSucceeds[app.context[]];
}

Cuối cùng, ứng dụng của chúng tôi đã kết nối thành công bằng ứng dụng của chúng tôi. tệp thuộc tính

3. 1. Ghi đè thuộc tính bằng đối số dòng lệnh

Chúng tôi có thể ghi đè tệp thuộc tính của mình khi chạy ứng dụng của mình bằng các đối số dòng lệnh. Chúng được chuyển đến ứng dụng khi chạy bằng lệnh java, lệnh mvn hoặc cấu hình IDE. Phương pháp cung cấp những thứ này sẽ phụ thuộc vào lệnh chúng tôi đang sử dụng

Hãy xem một ví dụ sử dụng mvn để chạy ứng dụng Spring Boot của chúng ta

mvn spring-boot:run -Dspring-boot.run.arguments='--spring.data.mongodb.port=7017 --spring.data.mongodb.host=localhost'

Để sử dụng nó, chúng tôi chỉ định các thuộc tính của mình làm giá trị cho spring-boot. chạy. đối số đối số. Chúng tôi sử dụng tên thuộc tính giống nhau nhưng thêm tiền tố vào hai dấu gạch ngang. Kể từ Spring Boot 2, nhiều thuộc tính phải được phân tách bằng dấu cách. Cuối cùng, sau khi chạy lệnh, sẽ không có lỗi

Các tùy chọn được định cấu hình theo cách này luôn được ưu tiên hơn tệp thuộc tính. Tùy chọn này hữu ích khi chúng ta cần thay đổi các tham số ứng dụng mà không thay đổi tệp thuộc tính của mình. Chẳng hạn, nếu thông tin đăng nhập của chúng tôi đã thay đổi và chúng tôi không thể kết nối nữa

Để mô phỏng điều này trong các thử nghiệm của chúng tôi, chúng tôi có thể đặt thuộc tính hệ thống trước khi chạy ứng dụng của mình. Ngoài ra, chúng tôi có thể ghi đè ứng dụng của chúng tôi. thuộc tính với phương thức thuộc tính

@Test
public void givenPrecedence_whenSystemConfig_thenInsertSucceeds[] {
    System.setProperty["spring.data.mongodb.host", HOST];
    System.setProperty["spring.data.mongodb.port", PORT];
    System.setProperty["spring.data.mongodb.database", DB];
    System.setProperty["spring.data.mongodb.username", USER];
    System.setProperty["spring.data.mongodb.password", PASS];

    SpringApplicationBuilder app = new SpringApplicationBuilder[SpringMongoConnectionViaPropertiesApp.class];
      .properties[
        "spring.data.mongodb.host=oldValue",
        "spring.data.mongodb.port=oldValue",
        "spring.data.mongodb.database=oldValue",
        "spring.data.mongodb.username=oldValue",
        "spring.data.mongodb.password=oldValue"
      ];
    app.run[];

    assertInsertSucceeds[app.context[]];
}

Do đó, các giá trị cũ trong tệp thuộc tính của chúng tôi sẽ không ảnh hưởng đến ứng dụng của chúng tôi vì các thuộc tính hệ thống được ưu tiên hơn. Điều này có thể hữu ích khi chúng tôi cần khởi động lại ứng dụng của mình với các chi tiết kết nối mới mà không cần thay đổi mã

3. 2. Sử dụng thuộc tính URI kết nối

Cũng có thể sử dụng một thuộc tính thay vì máy chủ, cổng riêng lẻ, v.v.

spring.data.mongodb.uri="mongodb://admin:[email protected]:27017/baeldung"

Thuộc tính này bao gồm tất cả các giá trị từ các thuộc tính ban đầu, vì vậy chúng tôi không cần chỉ định tất cả năm. Hãy kiểm tra định dạng cơ bản

________số 8

Phần cơ sở dữ liệu trong URI, cụ thể hơn là DB xác thực mặc định. Quan trọng nhất là mùa xuân. dữ liệu. mongodb. thuộc tính uri không thể được chỉ định dọc theo từng thuộc tính riêng lẻ cho Máy chủ, cổng và thông tin đăng nhập. Nếu không, chúng tôi sẽ gặp lỗi sau khi chạy ứng dụng của mình

@Test
public void givenConnectionUri_whenAlsoIncludingIndividualParameters_thenInvalidConfig[] {
    System.setProperty[
      "spring.data.mongodb.uri", 
      "mongodb://" + USER + ":" + PASS + "@" + HOST + ":" + PORT + "/" + DB
    ];

    SpringApplicationBuilder app = new SpringApplicationBuilder[SpringMongoConnectionViaPropertiesApp.class]
      .properties[
        "spring.data.mongodb.host=" + HOST,
        "spring.data.mongodb.port=" + PORT,
        "spring.data.mongodb.username=" + USER,
        "spring.data.mongodb.password=" + PASS
      ];

    BeanCreationException e = assertThrows[BeanCreationException.class, [] -> {
        app.run[];
    }];

    Throwable rootCause = e.getRootCause[];
    assertTrue[rootCause instanceof IllegalStateException];
    assertThat[rootCause.getMessage[]
      .contains["Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified"]];
}

Cuối cùng, tùy chọn cấu hình này không chỉ ngắn hơn mà đôi khi còn cần thiết. Đó là bởi vì một số tùy chọn chỉ khả dụng thông qua chuỗi kết nối. Chẳng hạn, sử dụng mongodb+srv để kết nối với bộ bản sao. Do đó, chúng tôi sẽ chỉ sử dụng thuộc tính cấu hình đơn giản hơn này cho các ví dụ tiếp theo

4. Thiết Lập Java Với MongoClient

MongoClient đại diện cho kết nối của chúng tôi với cơ sở dữ liệu MongoDB và luôn được tạo dưới mui xe. Tuy nhiên, chúng ta cũng có thể thiết lập nó theo chương trình. Mặc dù dài dòng hơn, phương pháp này có một vài ưu điểm. Chúng ta hãy xem xét chúng trong các phần tiếp theo

4. 1. Kết nối qua AbstractMongoClientConfiguration

Trong ví dụ đầu tiên của chúng tôi, chúng tôi sẽ mở rộng lớp AbstractMongoClientConfiguration từ Spring Data MongoDB trong lớp ứng dụng của chúng tôi

private void assertInsertSucceeds[ConfigurableApplicationContext context] {
    String name = "A";

    MongoTemplate mongo = context.getBean[MongoTemplate.class];
    Document doc = Document.parse["{\"name\":\"" + name + "\"}"];
    Document inserted = mongo.insert[doc, "items"];

    assertNotNull[inserted.get["_id"]];
    assertEquals[inserted.get["name"], name];
}
0

Tiếp theo, hãy thêm các thuộc tính mà chúng ta sẽ cần

private void assertInsertSucceeds[ConfigurableApplicationContext context] {
    String name = "A";

    MongoTemplate mongo = context.getBean[MongoTemplate.class];
    Document doc = Document.parse["{\"name\":\"" + name + "\"}"];
    Document inserted = mongo.insert[doc, "items"];

    assertNotNull[inserted.get["_id"]];
    assertEquals[inserted.get["name"], name];
}
1

Để làm rõ, các thuộc tính này có thể được mã hóa cứng. Ngoài ra, họ có thể sử dụng các tên khác với các biến Dữ liệu mùa xuân dự kiến. Quan trọng nhất, lần này, chúng tôi đang sử dụng một URI thay vì các thuộc tính kết nối riêng lẻ, không thể trộn lẫn. Do đó, chúng tôi không thể sử dụng lại ứng dụng của mình. thuộc tính cho ứng dụng này và chúng ta nên chuyển nó đi nơi khác

AbstractMongoClientConfiguration yêu cầu chúng tôi ghi đè getDatabaseName[]. Đó là vì tên cơ sở dữ liệu không bắt buộc trong URI

private void assertInsertSucceeds[ConfigurableApplicationContext context] {
    String name = "A";

    MongoTemplate mongo = context.getBean[MongoTemplate.class];
    Document doc = Document.parse["{\"name\":\"" + name + "\"}"];
    Document inserted = mongo.insert[doc, "items"];

    assertNotNull[inserted.get["_id"]];
    assertEquals[inserted.get["name"], name];
}
2

Tại thời điểm này, vì chúng tôi đang sử dụng các biến Dữ liệu mùa xuân mặc định, chúng tôi đã có thể kết nối với cơ sở dữ liệu của mình. Ngoài ra, MongoDB tạo cơ sở dữ liệu nếu nó không tồn tại. Hãy kiểm tra nó

private void assertInsertSucceeds[ConfigurableApplicationContext context] {
    String name = "A";

    MongoTemplate mongo = context.getBean[MongoTemplate.class];
    Document doc = Document.parse["{\"name\":\"" + name + "\"}"];
    Document inserted = mongo.insert[doc, "items"];

    assertNotNull[inserted.get["_id"]];
    assertEquals[inserted.get["name"], name];
}
3

Cuối cùng, chúng ta có thể ghi đè mongoClient[] để có lợi thế hơn cấu hình thông thường. Phương pháp này sẽ sử dụng biến URI của chúng tôi để xây dựng ứng dụng khách MongoDB. Bằng cách đó, chúng ta có thể có một tham chiếu trực tiếp đến nó. Chẳng hạn, điều này cho phép chúng tôi liệt kê tất cả các cơ sở dữ liệu có sẵn từ kết nối của chúng tôi

private void assertInsertSucceeds[ConfigurableApplicationContext context] {
    String name = "A";

    MongoTemplate mongo = context.getBean[MongoTemplate.class];
    Document doc = Document.parse["{\"name\":\"" + name + "\"}"];
    Document inserted = mongo.insert[doc, "items"];

    assertNotNull[inserted.get["_id"]];
    assertEquals[inserted.get["name"], name];
}
4

Định cấu hình kết nối theo cách này rất hữu ích nếu chúng ta muốn kiểm soát hoàn toàn việc tạo ứng dụng khách MongoDB

4. 2. Tạo MongoClientFactoryBean tùy chỉnh

Trong ví dụ tiếp theo của chúng tôi, chúng tôi sẽ tạo một MongoClientFactoryBean. Lần này, chúng ta sẽ tạo một thuộc tính gọi là tùy chỉnh. uri để giữ cấu hình kết nối của chúng tôi

private void assertInsertSucceeds[ConfigurableApplicationContext context] {
    String name = "A";

    MongoTemplate mongo = context.getBean[MongoTemplate.class];
    Document doc = Document.parse["{\"name\":\"" + name + "\"}"];
    Document inserted = mongo.insert[doc, "items"];

    assertNotNull[inserted.get["_id"]];
    assertEquals[inserted.get["name"], name];
}
5

Với phương pháp này, chúng tôi không cần mở rộng AbstractMongoClientConfiguration. Ngoài ra, chúng tôi có quyền kiểm soát việc tạo MongoClient của chúng tôi. Chẳng hạn, bằng cách gọi mongo. setSingleton[false], chúng tôi có một khách hàng mới mỗi khi chúng tôi gọi mongo. getObject[], thay vì một singleton

4. 3. Đặt chi tiết kết nối với MongoClientSettingsBuilderCustomizer

Trong ví dụ cuối cùng của chúng tôi, chúng tôi sẽ sử dụng MongoClientSettingsBuilderCustomizer

private void assertInsertSucceeds[ConfigurableApplicationContext context] {
    String name = "A";

    MongoTemplate mongo = context.getBean[MongoTemplate.class];
    Document doc = Document.parse["{\"name\":\"" + name + "\"}"];
    Document inserted = mongo.insert[doc, "items"];

    assertNotNull[inserted.get["_id"]];
    assertEquals[inserted.get["name"], name];
}
6

Chúng tôi sử dụng lớp này để tùy chỉnh các phần kết nối của mình nhưng vẫn có cấu hình tự động cho phần còn lại. Hữu ích khi chúng ta chỉ cần đặt một vài thuộc tính theo chương trình

5. Phần kết luận

Trong bài viết này, chúng ta đã thấy các công cụ khác nhau do Spring Data MongoDB mang lại. Chúng tôi đã sử dụng chúng để tạo kết nối theo những cách khác nhau. Ngoài ra, chúng tôi đã xây dựng các trường hợp thử nghiệm để đảm bảo các cấu hình của chúng tôi hoạt động như dự kiến. Trong khi đó, chúng tôi đã thấy mức độ ưu tiên cấu hình có thể ảnh hưởng đến thuộc tính kết nối của chúng tôi

Có cần phải đóng kết nối MongoDB không?

Không cần phải đóng kết nối một cách rõ ràng . Bằng cách này, ứng dụng tránh tạo và đóng kết nối [đây là một hoạt động tốn kém].

MongoDB có sử dụng tổng hợp kết nối không?

bộ định tuyến mongos có nhóm kết nối cho từng nút trong cụm .

Làm cách nào để đóng cơ sở dữ liệu MongoDB?

Một lớp lót để bắt đầu hoặc dừng dịch vụ mongodb bằng dòng lệnh; .
Để bắt đầu sử dụng dịch vụ. BẮT ĐẦU MẠNG MONGODB
Để ngừng sử dụng dịch vụ. NET DỪNG MONGODB

Làm cách nào để tìm các kết nối nhàn rỗi trong MongoDB?

Các kết nối trong MongoDB không bị ràng buộc với một không gian tên cụ thể [cơ sở dữ liệu và/hoặc bộ sưu tập]. Mặc dù không có lệnh riêng biệt nào cho phép người vận hành liệt kê tất cả các kết nối máy khách được thiết lập cho một phiên bản MongoDB cụ thể, nhưng bạn có thể sử dụng db. lệnh currentOp[] cho mục đích đó.

Chủ Đề