2 Ocak 2020 Perşembe

SpringData JPA @Query Anotasyonu - JQPL veya Native SQL Kullanıbilmeyi Sağlar

Giriş
Şu satırları dahil ederiz.
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
SpringData JPA ile

1. Derived Query
2. Custom Query
  2.1 JPQL custom query
  2.2. Native Custom Query kullanılabilir

@Query anotasyonu ile 2. maddedeki Custom Query yapılabilir.

Not : Hibernate ile gelen @Subselect Anotasyonu da Native SQL için kullanılabilir.

Kullanım İçin Bazı Maddeler
- JPA kullanırken kendi metodlarımıza JPQL/SQL verebilmeyi sağlar. Özellikle LAZY ilişki varsa bu anotasyon EAGER sonuçlar elde edilebilir.

- Veriyi değiştiren metodlar @Modifying olarak işaretli olmalı.

- Sorgularda Spring veri tabanından gelen veriyi metodun döndürdüğü tipe çevirmeyi biliyor olmalı. Yoksa Spring exception fırlatır.

- Sorgularda SpEL kullanılabilir. Açıklaması şöyle.
As of Spring Data JPA release 1.4 we support the usage of restricted SpEL template expressions in manually defined queries via @Query
-Sorgularda metoda geçen parametreler @Param olarak işaretli ise @Query içinde kullanılabilir.

SpEL ve Parametrenin Alanı
Açıklaması şöyle
Parameters are exposed for indexed access ([0] in the first method) or via the name declared using @Param. The actual SpEL expression binding is either triggered by ?# or :#. We support both types to allow you to be consistent to standard JPQL parameter bindings that also might occur in the query definition.
:#{#foo.field} şeklinde kullanılır
Örnek
Şöyle yaparız.
interface UserRepository extends CrudRepository<User, Integer> {
  @Query(nativeQuery=true,
    value=
      "select * from user "
    + "inner join address a on a.id = u.addressId "
    + "where a.street = :#{#address.street}")
  List<User> findByAddress(@Param("address") Address address);
}
SpEL ve entityName
 SpEL ile gelen anahtar kelimelerden birisi entityName. Şöyle yaparız
@Query("select u from #{#entityName} u where u.lastname = ?1")

SpEL ve In
in(:#foo.![field]}) şeklinde kullanılır.

Örnek
Şöyle yaparız
"where a.street in(:#{#address.![street]})")
Normal Kullanım
@Query
Örnek
Elimizde şöyle bir kod olsun.
public interface BoundsDataRepository extends CrudRepository<Bound, Long> {
  ...   
}
Şöyle yaparız.
@Query("from Bound b where b.startTimeStamp <= :currentTimeStamp and "
        + "b.endTimeStamp >= :currentTimeStamp")
List<Bound> findByCurrentTimeStamp(@Param("currentTimeStamp") Timestamp currentTimeStamp);
Örnek
Şöyle yaparız.
@Query("select e from entity e where e.column1 = e.column2")
List<Entity> findByColumn1EqualsColumn2();
nativeQuery Alanı
nativeQuery Alanı yazısına taşıdım.

value Alanı
Sql cümlesini içerir. Şöyle yaparız
@Query(value="SELECT SUM(revenue) AS revenue FROM events WHERE event_id = :event_id",
  nativeQuery = true)
public List<Foo> findTicketTotalForAnEvent(@Param("event_id") String event_id);

1. : ile isim parametresi
@Query Anotasyonu ve Named Parameter yazısına taşıdım

2. ? ile pozisyon parametresi
Örnek - delete
Elimizde şöyle bir kod olsun.
@Query(value = "delete from bin_values where id in
(select bv.id from bin_values bv inner join bin b on
bv.bin_id = b.id where b.stat_id = ?1)", nativeQuery = true)
void deleteByStatId(long statId);
Bu cümle @Modifying olarak işaretli olmadığı için şu hatayı alırız.
Exception in thread "main" org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet
Caused by: org.hibernate.exception.GenericJDBCException: could not extract ResultSet
Caused by: java.sql.SQLException: Query does not return results
Örnek - update
Şöyle yaparız.
@Modifying
@Query("update User u set u.firstname = ?1, u.lastname = ?2 where u.id = ?3")
void setUserInfoById(String firstname, String lastname, Integer userId);
Örnek - update
Şöyle yaparız.
@Modifying
@Query("UPDATE MyObject obj SET obj.deleted = true WHERE obj.objectId = ?1")
void deleteById(UUID uuid);
3. Join + Where =
SpringData JpaRepository ile @Query ve Join yazısına taşıdım.

4. Join + Where In
JpaRepository ile @Query ve In Clause yazısına taşıdım

Hiç yorum yok:

Yorum Gönder