"Enter"a basıp içeriğe geçin

Spring Boot 2.x ile backend -4

Bir önceki yazımızda ORM, JPA, Hibernate gibi temel kavramlar ve Spring Boot üzerinde entity’leri nasıl oluşturacağımızdan bahsetmiştik. Bu yazımızda temel veritabanı işlemlerinin bu entity’ler üzerinde nasıl gerçekleştirebileceğimizi, özetle entity üzerinde CRUD (Create-Read-Update-Delete) operasyonlarını anlatacağım.

CRUD Repository oluşturma

Spring Boot Data JPA, entity sınıfları üzerinde CRUD fonksiyoneliteleri sağlamak için CrudRepository interface’i sağlamaktadır. CrudRepository interface’i, CRUD operasyonları için temel metodları içerir. Aşağıda temel bazı metodlar ve açıklamaları sıralanmıştır;

MetodAçıklama
long count() entity sayısını döner
Iterable<T> findAll() verilen tipteki tüm item’ları döner
Optional<T> findById(ID Id) primary key (ID) değerine göre tek item döner
void delete(T entity) entity’i siler
void deleteAll() repository’den tüm entity’leri siler
<S extends T> save(S entity) enitity’i kaydeder

Repository sınıflarımızı domain paketi altında oluşturacağız, bu işlem için yeni bir domain paketi (com.my.mybackend.domain) ve bu paketin içine daha önce oluşturduğumuz Subscriber entity’miz için SubscriberRepository isminde yeni bir interface oluşturuyoruz.

SubscriberRepository interface’i, Spring Boot JPA Data Repository içerisindeki CrudRepository interface’inden extend etmeli ve Entity sınıfımızın ismini ve ID değer tipini parametre olarak almalıdır. Aşağıda SubscriberRepository interface’inin temel kod yapısı verilmiştir.

package com.my.mybackend.domain;

import com.my.mybackend.model.Subscriber;
import org.springframework.data.repository.CrudRepository;

public interface  SubscriberRepository extends CrudRepository <Subscriber, Long>{

}

CRUD işlemleri için üzerinde operasyonlarımızı uygulayacağımız veri setine ihtiyacımız var, önceki yazımızda uygulamamıza eklediğimiz in memory database’imiz üzereinde konsolu kullanarak manuel veri girişi yapabiliriz ancak, sistemi her başlattığımızda database resetlenip yeniden oluşturulacağı için her defasında manuel veri girişi pek pratik bir yöntem olmayacaktır. Bu sorunu ortadan kadırmak için, sistemi her başlattığımızda otomatik olarak belli bir veri setini kaydedecek şekilde kodumuzda CrudRepository interface’inin save metodunu ve Spring Boot’un CommandLineRunner interface’ini kullanarak değişiklik yapacağız.

Ana sınıfımız (MybackendApplication.java) içerisine aşağıdaki kod bloğunu ekliyoruz;

@Bean
    CommandLineRunner runner() {
        return args -> {
            // Place your code here
        };

    }

Şimdi veri setimizi kaydetmek için metodlarımızı oluşturabilir ve CommandLinerunner içinden çağırabiliriz. Subscriber repository’imizi ana sınıfımıza enjecte etmek için @AutoWired anotasyonunu kullanacağız. @AutoWired; dependency injection için kullanılan bir anotasyondur. Repository’mizi enjecte ettikten sonra CommandLineRunner içerisine save metodlarımızı ekleyebiliriz. Ana sınıfımıza ait kod bloğu aşağıdaki gibi olacaktır;

package com.my.mybackend;

import com.my.mybackend.domain.SubscriberRepository;
import com.my.mybackend.model.Subscriber;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class MybackendApplication {
    private static final Logger logger = LoggerFactory.getLogger(MybackendApplication.class);

    @Autowired
    private SubscriberRepository repository;

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

    @Bean
    CommandLineRunner runner() {
        return args -> {
            // Save demo data to database
            repository.save(new Subscriber("Mehmet", "Yazici", 1981, "Male", 38, "test kaydi1"));
            repository.save(new Subscriber("Ahmet", "Yilmaz", 1979, "Male", 40, "test kaydi2"));
            repository.save(new Subscriber("Zeynep", "Kaya", 1970, "Female", 49, "test kaydi3"));

        };
    }
}

Yine uygulamayı çalıştırdığımızda aşağıdaki gibi logların basıldığını ve H2 konsolundan kontrol ettiğimizde de, test verilerinin tabloya yazıldığını görebiliriz.

Basit sorgular:

Spring Data Repository ile kendi sorgularımızı oluşturabilir ve özelleştirebiliriz. Sorgularımız her zaman bir prefix ile başlamalı, sorgu çekilecek kolon ismine denk gelen entity parametresini (veya parametrelerini) içermelidir. Aşağıda kullanılan temel operatörler ve kullanım şekillerine ilişkin (SubscriberRepository sınıfı içerisinde) örnekler sıralanmıştır;

  • Tek parametre ile bir sorgu çekeceğimiz zaman findBy prefix’ini kullanabiliriz:
 //Fetch subs. by name
    List<Subscriber> findByName(String name);
  • Birden fazla parametre ile sorgu çekeceğimiz zaman, findBy ile birlikte parametreler arasında And ve Or notasyonunu de kullanmamız gerekir:
 //Fetch subs. by name and surname
    List<Subscriber> findByNameAndSurname(String name, String surname);
  • Sorgu sonucumuzu sıralamak istediğimiz taktirde OrderBy kullanmamız gerekir:
//Fetch subs. by name and surname and sort by age
    List<Subscriber> findByNameAndSurnameOrderByAgeAsc(String name, String surname);
  • Spesifik bir SQL cümlesi kullanmak istiyorsak @Query anotasyonunu kullanıyoruz:
//Fetch subs. by name using SQL statement
    @Query(" select  t1 from Subscriber  t1 where t1.name like ?1%")
    List<Subscriber> findByNameStartingWith(String name);

Yukarıda temel bazı operatörler hakkında özet bilgi verdim, farklı notayonlar kullanarak daha özelleşmiş advanced seviye sorgular oluşturabilir ve bunları kullanabiliriz. SubscriberRepository sınıfımızın görünümü aşağıdaki gibi olacaktır:

package com.my.mybackend.domain;

import com.my.mybackend.model.Subscriber;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface SubscriberRepository extends CrudRepository<Subscriber, Long> {

    //Fetch subs. by name
    List<Subscriber> findByName(String name);

    //Fetch subs. by name and surname
    List<Subscriber> findByNameAndSurname(String name, String surname);

    //Fetch subs. by name and surname and sort by age
    List<Subscriber> findByNameAndSurnameOrderByAgeAsc(String name, String surname);

    //Fetch subs. by name using SQL statement
    @Query(" select  t1 from Subscriber  t1 where t1.name like ?1%")
    List<Subscriber> findByNameStartingWith(String name);

}

Sorgu sonuçlarının uzun listeler halinde elde edildiği durumlarda Spring Data JPA bize CrudRepository den extend edilmiş PagingAndSortingRepository sunar. Kullanımı CrudRepository ile aynıdır:

import org.springframework.data.repository.PagingAndSortingRepository;

public interface SubscriberRepository extends PagingAndSortingRepository<Subscriber, Long> {

}

bu durumda repository iki ek metod sağlar:

Iterable<T> findAll(Sort sort)Belirtilen opsiyona göre sıralanmış şekilde değerleri döner.
Page<T> findAll(Pageable pageable)Belirtilen sayfalama opsiyonuna göre değerleri döner.