Merhabalar arkadaşlar. Bu yazı içerisinde sizlere Spring Boot tabanlı bir projeinin nasıl MongoDB ile birlikte kullanılabileceğini anlatacağım.

Bu yazıdaki kodların yer aldığı uygulamaya https://github.com/ilkgunel/SpringBootMongoDB adresinden erişebilirsiniz.

Bu yazı için işlemlerimizi Characters collection’ı ile yapacağız. İlk olarak mevcutta bulunan veritabanımız içerisinde yer alan Characters Collection’ına ve tuttuğu verilere bakalım.

db.Characters.find(); komutu ile Characters collection’ı içerisinde tutulan verileri çekiyorum ve 2 kayıt geldiğini görüyorum. Bunlar benim yazıdan önce test amaçlı eklediğim veriler.

Şimdi Spring Boot projesi ile MongoDB nasıl birbirne bağlanıp kullanılabilir bunu inceleyelim.

pom.xml

pom.xml dosyasında sadece 2 adet bağımlılığımız var. Bunlar Rest API ayağa kaldırmak için ihtiyacımız olan spring-boot-starter-web ve projemizi MongoDB ile beraber çalıştırmak için ihtiyacımız olan spring-boot-starter-data-mongodb bağımlılıkları.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ilkaygunel</groupId>
    <artifactId>SpringBootMongoDB</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
</project>

application.properties

Projemizin MongoDB ile bağlantı kurabilmesi için gerekli tanımlamalar application.properties dosyası içerisinde yapılacak.

server.servlet.context-path=/CharactersAPIProject
server.port=8080

#mongodb
#spring.data.mongodb.username=root
#spring.data.mongodb.password=root
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=SampleDatabase

Yukarıda görebileceğimiz gibi projeyi MongoDB’ye bağlayabilmek için 5 adet ayar ifademiz mevcut. Bunlardan ilk ikisi kapalı çünkü benim bilgisayarımda çalışan MongoDB bir username password ikilisine sahip değil. Siz ihtiyaç duyduğunuzda bu 2 ifadeyi kullanabilirsiniz. 3. ifade bağlanacağımız MongoDB veritabanının host adresini, 4. ifade port adresini ve 5. ifade de ismini istiyor bizlerden.

Characters.java

Klasik RDBMS yapısından hatırlayacağımız gibi veritabanımızdaki tablolarımız projemizdeki entity’lerimize karşılık geliyor. NoSQL yapısında ise tabloların yerlerini Collection’lar alıyor ve Collection’lar içerisinde her bir kayıt dokuman olarak tutuluyor. Aşağıdaki kodumuzda da görebileceğiniz gibi Characters collection’ına karşılık gelecek olan Characters.java sınıfımızı @Document notasyonu ile işaretliyoruz. Bu notasyon bu sınıfın tuttuğu verilerin MongoDB’ye nasıl mapleneceğini söylüyor. Bu notasyona parametre olarak verdiğimiz collection = “Characters” ifadesi ile de bu sınıfın verilerinin Characters collection’ında tutulacağını bildiriyoruz.

package com.ilkaygunel.entity;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "Characters")
public class Characters {
    @Id
    private Long id;

    @Indexed(unique = true)
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

CharactersRepository.java

CharactersRepository bizim veritabanı işlemleri için kullanacağımız ve Spring tarafından otomatik olarak instance’ı oluşturulacak bir interface’dir. Biz CharactersRepository interface’ini MongoRepository interface’inden kalıtıyoruz ve kalıtma sırasında Characters sınıfı ile onun ID alanının tipini veriyoruz.

package com.ilkaygunel.repository;

import com.ilkaygunel.entity.Characters;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CharactersRepository extends MongoRepository<Characters,Long> {
}

CharactersService.java

CharactersService sınıfı bizim klasik Spring’den aşina olduğumuz bir servis sınıfı. Business Logic bu katmanda gerçeklenecek. CharactersService sınıfımızı @Service notasyonu ile işaretliyoruz ve içerisinde az önce bahsi geçen CharactersRepository tipinde bir objeyi @Autowired notasyonu ile inject ediyoruz. Az önce bahsettiğim gibi bu obje Spring tarafından doldurulacak.

package com.ilkaygunel.service;

import com.ilkaygunel.entity.Characters;
import com.ilkaygunel.repository.CharactersRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CharactersService {

    @Autowired
    private CharactersRepository charactersRepository;

    public void saveCharacter(Characters characters) {
        charactersRepository.save(characters);
    }

    public List<Characters> findAllCharacters() {
        return charactersRepository.findAll();
    }
}

CharactersApi.java

CharactersApi sınıfımız da Rest API endpoint olarak iş görecek sınıfımız. Client’dan gelen istekleri bu sınıfı karşılayacak. İçerisinde gelen veriyi kaydetmet için servise iletecek postCharacter ve veritabanındaki kayıtları listeleyecek allCharacters metotları yer alıyor.

package com.ilkaygunel.api;

import com.ilkaygunel.entity.Characters;
import com.ilkaygunel.service.CharactersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping(value = "/characters")
public class CharactersApi {

    @Autowired
    private CharactersService characterService;

    @RequestMapping(value = "/post", method = RequestMethod.POST)
    public ResponseEntity<String> postCharacter(@RequestBody Characters characters) {
        characterService.saveCharacter(characters);
        return new ResponseEntity<>("Kayıt İşlemi Başarılı!", HttpStatus.OK);
    }

    @RequestMapping(value = "/all", method = RequestMethod.GET)
    public ResponseEntity<List<Characters>> allCharacters() {
        List<Characters> characters = characterService.findAllCharacters();
        return new ResponseEntity<>(characters, HttpStatus.OK);
    }
}

Application.java

Application sınıfımız da uygulamamızı ayağa kaldırmak için kullanacağımız sınıfımız. @SpringBootApplication notasyonu dışında sınıfımız 3 notasyon ile daha işaretli. @EntityScan ile hangi path altında entity’lerin yer aldığını, @ComponentScan ile hangi path altındaki yerlerin Spring tarafından taranıp tanınması gerektiğini, @EnableMongoRepositories ile de MongoRepository’den kalıtılan interface’lerin hangi path altında olduğu bildirmiş oluyoruz.

package com.ilkaygunel.application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@SpringBootApplication
@EntityScan("com.ilkaygunel.entity")
@ComponentScan(basePackages = {"com.ilkaygunel.*"})
@EnableMongoRepositories("com.ilkaygunel.repository")
public class Application {

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

}

DEMO

Şimdi uygulamamızın bir demosunu yapalım.

Postman üzerinden http://localhost:8080/CharactersAPIProject/characters/all adresine bir GET isteğinde bulunuyorum ve uygulama da bana aşağıdaki ekran görüntüsün de görebileceğimiz gibi yazının başında gördüğümüz 2 kaydı cevap olarak dönüyor.

Şimdi de /post path’ine istek göndererek kayıt işlemine bir bakalım.

http://localhost:8080/CharactersAPIProject/characters/post adresine Content-Type:application/json header’ına sahip bir POST isteğinde bulunuyorum ve body kısmında aşağıdaki veriyi gönderiyorum:

{
	"id":3,
	"name":"Howard Wolowitz"
}

Response kısmında bana verinin başarılı şekilde kaydedildiğine dair bir mesaj dönüyor.

MongoDB’ye gidip baktığımda da verinin başarılı şekilde kaydedilmöiş olduğunu görüyorum.

Bu yazıda anlatacaklarım da bu kadar arkadaşlar. Bir sonraki yazıda görüşmek üzere.

Görüşene kadar sağlıcakla kalın.