Thursday, January 15, 2015

Spring Data MongoDB ile Spring MongoDB entegrasyonu

Spring Data projesi ile MongoDB'ye erişmek kolay bir hal alıyor.

Kodlara GitHub üzerinden erişebilirsiniz.

spring-boot-starter-data-mongodb'yi dependency olarak ekliyoruz.
pom.xml dosyası:

    org.springframework.boot
    spring-boot-starter-parent
    1.1.10.RELEASE


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



    
    UTF-8
    UTF-8
    org.guneriu.springboot.mongo.Application



    
        
            org.springframework.boot
            spring-boot-maven-plugin
        
    


MongoDB üzerinde CRUD işlemlerini yapabilmek için Spring-Data-MongoDB bize MongoRepository sınıfını sunuyor. Bu sınıf ile birlikte
"count, delete, delete, delete, deleteAll, exists, findAll, findOne, save" operasyonları hazır halde geliyor. Bununla birlikte bu metodlara geçirebileceğimiz "Pageable" ve "Sort" parametreleri ile paging ve sorting işlemlerini de yapabiliyoruz.

Customer sınıfı:
import org.springframework.data.annotation.Id;

public class Customer {

    @Id
    private String id;
    private String firstName;
    private String lastName;

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return String.format("Customer[id=%s, firstName='%s', lastName='%s']",
                id, firstName, lastName);
    }
}

CustomerRepository sınıfı.
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;

public interface CustomerRepository extends MongoRepository<Customer string=""> {

    public List<Customer> findByFirstName(String firstName);
    public List<Customer> findByLastName(String lastName);

    @Query(value = "{}", count = true)
    public int customerCount();

    @Query(value = "{$or:[{'firstName': '?0'}, {'lastName': '?0'}]}", count = true)
    public int customersCountByFirstNameOrLastName(String name);
}

Buradaki findByFirstName ve findByLastName için bir kod bloğu yazmadım. Spring property expression ile sınıf üzerindeki alanlar ile metod ismini eşleştirip bizim için sorguları oluşturuyor. Aşağıdaki örnek kullanımlar Spring-Data-Mongo referans dökümanından. Bazen kompleks sorgular yazmanız gerektiğinde native sorgular yazıp çalıştırabilirsiniz. Bunun için yukarıdaki örnekte görüldüğü gibi @Query annotasyonu içerisine sorguyu yazıyoruz '?0' parametre yerine geçen placeholder.

// Enabling ignoring case for an individual property
    List<Person> findByLastnameIgnoreCase(String lastname);
    // Enabling ignoring case for all suitable properties
    List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

    // Enabling static ORDER BY for a query
    List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
    List<Person> findByLastnameOrderByFirstnameDesc(String lastname);

MongoDB üzerinde işlem yapabilmek için Spring'in sunduğu diğer sınıf ise MongoTemplate. Bu örnek için MongoRepository yeterli geliyor ancak kullanımını göstermek için MongoTemplate yapılandırması aşağıdaki gibi.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;

import com.mongodb.Mongo;
import com.mongodb.MongoClient;

@Configuration
public class MongoConfig {

    @Bean
    public Mongo mongo() throws Exception {
        return new MongoClient();
    }

    @Bean
    public MongoOperations mongoTemplate() throws Exception {
        return new MongoTemplate(mongo(), "test");
    }

}

Uygulamayı çalıştıracağımız main metodumuzu yazdığımız Application sınıfı aşağıdaki gibi.

import java.util.Arrays;
import java.util.List;

import org.guneriu.springboot.mongo.config.MongoConfig;
import org.guneriu.springboot.mongo.customer.Customer;
import org.guneriu.springboot.mongo.customer.CustomerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

@EnableAutoConfiguration
@Import(MongoConfig.class)
public class Application implements CommandLineRunner {

    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    private MongoOperations mongoOperations;

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

    @Override
    public void run(String... args) throws Exception {

     Customer customer1 = new Customer("James", "Gosling");
     Customer customer2 = new Customer("James", "Joyce");
     Customer customer3 = new Customer("Joshua", "Bloch");

     customerRepository.save(Arrays.asList(customer1, customer2, customer3));

     List<Customer> customers = customerRepository.findAll();

     System.out.println("listing all customers");

     for (Customer customer : customers) {
        System.out.println(customer);
     }

     List<Customer> customersByFirstName = customerRepository.findByFirstName("James");

     System.out.println("customers with firstName James");

     for (Customer customer : customersByFirstName) {
        System.out.println(customer);
     }

     List<Customer> customersByFirstNameAndLastName =
            mongoOperations.find(
                    new Query(new Criteria().andOperator(
                            Criteria.where("firstName").is("Joshua"),
                            Criteria.where("lastName").is("Bloch"))),
                            Customer.class);

     System.out.println("customers with firstName Joshua and lastName Bloch");

     for (Customer customer : customersByFirstNameAndLastName) {
         System.out.println(customer);
     }

     System.out.println("all costumer counts: " + customerRepository.customerCount());
     System.out.println("customer count firstName or lastName is James :"
             + customerRepository.customersCountByFirstNameOrLastName("James"));
    }
}

Uygulamayı terminal'den spring-boot maven eklentisini kullanarak yada "Run As Java Application" diyerek çalıştırabiliriz.
Uygulamayı çalıştırdığımızda aldığımız çıktı aşağıdaki gibi.

ugur@ugur-PC:~/dev/workspace/spring-boot-mongo$ mvn spring-boot:run
listing all customers
Customer[id=54b7062544aefa551023948f, firstName='James', lastName='Gosling']
Customer[id=54b7062544aefa5510239490, firstName='James', lastName='Joyce']
Customer[id=54b7062544aefa5510239491, firstName='Joshua', lastName='Bloch']
customers with firstName James
Customer[id=54b7062544aefa551023948f, firstName='James', lastName='Gosling']
Customer[id=54b7062544aefa5510239490, firstName='James', lastName='Joyce']
customers with firstName Joshua and lastName Bloch
Customer[id=54b7062544aefa5510239491, firstName='Joshua', lastName='Bloch']
all costumer counts: 3
customer count firstName or lastName is James :2