JpaRepository ve JpaSpecificationExecutor
Published: 2024-06-22 14:56:48

### JpaRepository
`JpaRepository`, Spring Data JPA tarafından sağlanan ve JPA (Java Persistence API) tabanlı veri erişim katmanını kolaylaştırmak için kullanılan bir arayüzdür. `JpaRepository` arayüzü, CRUD (Create, Read, Update, Delete) işlemlerini gerçekleştirmek için çeşitli metodlar sağlar. Bu arayüz, `PagingAndSortingRepository` arayüzünü genişletir, bu nedenle veri kümesini sayfalandırma ve sıralama desteği de sunar.

#### Sağladığı Metodlar
`JpaRepository` arayüzü, veritabanı işlemleri için bir dizi hazır metod içerir:

- **save(S entity)**: Verilen varlığı kaydeder veya günceller.
- **findById(ID id)**: Verilen kimlik değeri ile varlığı bulur.
- **findAll()**: Tüm varlıkları döner.
- **findAll(Pageable pageable)**: Tüm varlıkları sayfalandırılmış biçimde döner.
- **deleteById(ID id)**: Verilen kimlik değeri ile varlığı siler.
- **count()**: Varlıkların toplam sayısını döner.
- **existsById(ID id)**: Verilen kimlik değeri ile bir varlığın olup olmadığını kontrol eder.

#### Kullanım
`JpaRepository` arayüzünü kullanarak, veritabanı işlemleri için gerekli temel metodları kolayca ekleyebilirsiniz. İşte bir örnek:

```java
package com.example.demo.repository;

import com.example.demo.model.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
    // Ekstra sorgular buraya eklenebilir
}
```

### JpaSpecificationExecutor
`JpaSpecificationExecutor`, Spring Data JPA tarafından sağlanan ve JPA kriter tabanlı sorgularını gerçekleştirmek için kullanılan bir arayüzdür. Bu arayüz, dinamik ve esnek sorgular oluşturmayı sağlar.

#### Sağladığı Metodlar
`JpaSpecificationExecutor` arayüzü, kriter tabanlı sorgular için çeşitli metodlar içerir:

- **findAll(Specification<T> spec)**: Verilen spesifikasyona uygun tüm varlıkları bulur.
- **findAll(Specification<T> spec, Pageable pageable)**: Verilen spesifikasyona uygun tüm varlıkları sayfalandırılmış biçimde bulur.
- **count(Specification<T> spec)**: Verilen spesifikasyona uygun varlıkların sayısını döner.
- **exists(Specification<T> spec)**: Verilen spesifikasyona uygun varlıkların olup olmadığını kontrol eder.

#### Kullanım
`JpaSpecificationExecutor` arayüzü, dinamik sorgular oluşturmak için kullanılır. Bu sorgular, `Specification` arayüzü kullanılarak tanımlanır. İşte bir örnek:

```java
package com.example.demo.repository;

import com.example.demo.model.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {
    // Ekstra sorgular ve spesifikasyonlar buraya eklenebilir
}
```

### Specification Kullanımı
`Specification` arayüzü, kriter tabanlı sorgular oluşturmak için kullanılır. İşte bir örnek:

```java
package com.example.demo.specification;

import com.example.demo.model.Product;
import org.springframework.data.jpa.domain.Specification;

public class ProductSpecification {

    public static Specification<Product> hasName(String name) {
        return (root, query, criteriaBuilder) ->
                criteriaBuilder.equal(root.get("name"), name);
    }

    public static Specification<Product> hasPrice(BigDecimal price) {
        return (root, query, criteriaBuilder) ->
                criteriaBuilder.equal(root.get("price"), price);
    }
}
```

Bu spesifikasyonlar daha sonra repository metodlarında kullanılabilir:

```java
import com.example.demo.model.Product;
import com.example.demo.repository.ProductRepository;
import com.example.demo.specification.ProductSpecification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    public List<Product> findProductsByNameAndPrice(String name, BigDecimal price) {
        return productRepository.findAll(
                Specification.where(ProductSpecification.hasName(name))
                             .and(ProductSpecification.hasPrice(price))
        );
    }
}
```

Bu şekilde, `JpaRepository` ve `JpaSpecificationExecutor` arayüzleri ile CRUD işlemleri ve dinamik sorgular için güçlü ve esnek bir veri erişim katmanı oluşturabilirsiniz.