@Query etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
@Query etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

1 Aralık 2020 Salı

SpringData JPA @Query Anotasyonu nativeQuery Alanı

Giriş
SpringData JPA ile

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

Bu yazıda 2.2 maddesindeki Native Custom Query anlatılıyor. Native Query ile veri tabanına direkt gönderilen SQL kastediliyor. 

Kullanım
- Native Query ile JPA'daki nesne tipinden sonuç döndürülebilir.
- Native Query ile insert/update, sort gibi işlemler yapılabilir.
- Native Query ile Projection döndürülebilir.
- Native Query ile "named parameter binding" yapılabilir. Yani SQL içinde ":foo" şeklide parametre isimleri olur
- Native Query ile "positional parameter binding" kullanılıp kullanılmadığını bilmiyorum

Örnek
Şöyle yaparız
@Query(value = "SELECT * FROM USERS u WHERE u.status = 1", nativeQuery = true)
Collection<User> findAllActiveUsersNative();
Örnek
Şöyle yaparız. Burada tek bir sütun çekildiği için Long listesi döndürülüyor
@Query(value="SELECT field FROM complex_innerquery", nativeQuery=true)
Collection<Long> getAllFieldValues();
Örnek
Şöyle yaparız. Burada birden fazla sütun çekildiği ancak nesnenin tamamı çekilmediği için Object[] listesi döndürülüyor
@Repository
public interface BatterRepository extends JpaRepository<Batter, Long> {
  @Query(value = "SELECT tb.id AS id, tb.title AS title FROM " +
            "  tbl_batter tb " +
            "WHERE tb.`title` LIKE %:searchKey%", nativeQuery = true)
  List<Object[]> getData(@Param("searchKey") String searchKey);
}
Örnek

Stored procedure çağırmak için şöyle yaparız.
@Query(value="EXEC dbo.spChartPracticeInternalDoctor ?, ?, ?, ?", nativeQuery = true)
List<ReportDataSet> foo(Long id, Date date,Long months, String tests);

15 Nisan 2020 Çarşamba

SpringData JpaRepository ile @Query ve Join - OneToMany Tarzı İlişkilerde Kullanılır

Giriş
Normal JPQL sorgusu yazıyoruz. Bu yöntem bence custom method eklemekten daha kolay.

Bu sorgularda dikkat edilmesi gereken şeyler şöyle
1. Join ile her zaman alias kullanmak gerekir.
2. Positional parameter kullanmak istersek =?1 gibi yazmak gerekir.
3. Parametre ismini kullamak istersek =:myparameter gibi yazmak gerekir.
Örnek - inner join
Şöyle yaparız.
@Query("select w from Way w join w.relations r where r.relationID=?1")
List<Way> selectAllWaysByRelationID(Long relationID);
Açıklaması şöyle.
When using JOIN you need to use alias of Way with relations field like this, w.relations r instead of Way.relations.

Örnek - LEFT JOIN FETCH
Place ->has -> City -> has -> State ilişkisi olsun. Şöyle yaparız.
public interface PlaceRepository extends
 JpaRepository<Place, Long>, PlaceRepositoryCustom {

  @Query(value = "SELECT p FROM Place p LEFT JOIN FETCH p.author
                  LEFT JOIN FETCH p.city c LEFT JOIN FETCH c.state 
                  where p.id = :id")
  Place findById(@Param("id") int id);
}

public interface CityRepository extends JpaRepository<City, Long>,
 CityRepositoryCustom { 
  @Query(value = "SELECT c FROM City c LEFT JOIN FETCH c.state where c.id = :id")
  City findById(@Param("id") int id);
}

30 Mart 2020 Pazartesi

SpringData JpaRepository ile @Query ve Join + Where In Clause - OneToMany Tarzı İlişkilerde Kullanılır

Giriş
In clause parent child ilişkisi varsa parent tarafına uygulanır.

Örnek
Şöyle yaparız.
public interface FileRepository extends CrudRepository<FileEntity, UUID> {
  @Query("SELECT f FROM FileEntity f JOIN MetadataEntity m on f.id = m.file_id
    WHERE (m.key, m.value) IN (:metadataKeyValue)")
  List<FileEntity> findAllByMetadataContains(@Param("metadataKeyValue")
    Map<String,String> metadataKeyValue);
}
Örnek
Elimizde şöyle bir kod olsun. Bu kod in clause seçimini child tarafına uygulamaya çalışıyor ancak beklenen sonucu vermez.
interface ParentRepo extends JpaRepo<Parent,Integer> {
  @Query("SELECT p FROM Parent p JOIN p.children c WHERE p.id = :parentId ando
          c.id IN(:childIds")
  Parent getParentByIdAndChildIds(int parentId, List<Integer> childIds)
}
Açıklaması şöyle.
My expectation is that calling

parentRepo.getParentByIdAndChildIds(1, Arrays.asList(1,2,3))

will return the parent object with only 3 child entities attached, but instead, I get ALL of the children (i.e. children with ids from 1-10).
Belki sadece child'lara erişmek için şöyle yaparız.
interface ChildRepository extends JpaRepository<Child, Integer> {
  @Query("SELECT c FROM Child c WHERE c.parent.id = :parentId and c.id IN(:childIds)")
  List<Child> getParentByIdAndChildIds(int parentId, List<Integer> childIds)
}