2 Şubat 2021 Salı

SpringData JpaRepository Derived Query - findByXXX

Giriş
findByXXX meodları metod isminden Entity nesnesinin kullanılacak üye alanına erişir. Bu metodlar şu tipleri dönebilir. Belirtilen alana ait sorgu otomatik üretilir.
1) Entity
2) Optional<Entity>
3) List<Entity>
4) Stream<Entity>
5) Page
6) Slice
Örnek - by field + paging
Sayfalama için şöyle yaparız.
Page<User> findByLastname(String lastname, Pageable pageable);

Slice<User> findByLastname(String lastname, Pageable pageable);
Açıklaması şöyle
"The first method allows you to pass an org.springframework.data.domain.Pageable instance to the query method to dynamically add paging to your statically defined query. A Page knows about the total number of elements and pages available. It does so by the infrastructure triggering a count query to calculate the overall number. As this might be expensive depending on the store used, Slice can be used as return instead. A Slice only knows about whether there’s a next Slice available which might be just sufficient when walking thought a larger result set."
Örnek
Elimizde şöyle bir kod olsun.
@Entity
@Table(name = "menu_item")
public class MenuItem {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;

  @Column
  private long parent;
  ...
  /* getters and setters... */
}
Şöyle yaparız. Tek bir nesne değil List döner.
@Repository
public interface MenuItemRepository  extends JpaRepository<MenuItem, Long> {

  //find all MenuItems By Parent
  public List<MenuItem> findByParent(long parent);

}
Örnek - nested field
Elimizde şöyle bir kod olsun
@Entity
@Table
public class QueuedBook implements Serializable {

  @Embedded
  @NotNull
  private BookId bookId;
   ...
}

@Embeddable
public class BookId implements Serializable {

  @NotNull
  @Size(min=1, max=40)
  private String bookId;

  @NotNull
  @Enumerated(EnumType.STRING)
  private Region region;
  ...
}
QueuedBookRepo sınıfına şu metodu ekleriz
Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);
Örnek
Benim elimizde şöyle bir kod vardı
public class Platform {
  @Elementcollection
  @CollectionTable(name="SUBSYTEMS",joinColumn(name="PLATFORM_ID"))
  @OrderColumn(name="POSITION")
  private List<Subsystem> items = new ArrayList<>();
  ...
}

@Embeddable
public class Subsystem {
  @ManyToOne
  @JoinColumn(name="ENTITY_ID")
  public Entity entity;
  ...
}
Gerçek nesne hiyerarşisi ise derindi
@Entity
@Table
public class Entity extends BaseEntity {
  ...
}
@Entity
@Table
public class BaseEntity extends BaseObject {
  ...
}
@Entity
@Table
@Inheritance(strategy = InheritanceType.JOINED)
public class BaseObject {
  @Id
  private String id;
}
PlatformRepository sınıfına şu metodu ekleriz. Burada ana nesnenin altındaki bir listenin içindeki bir alana göre find() yapılıyor
List<Platform> findByItemsEntityId(@Param("susbsystemId")String susbsystemId);
Üretilen sql kabaca şöyle
select ... from platform p 
  
left outer join entity e on p.id = e.platform_id
left outer join base_entity be on p.id=be.id
left outer join base bo on p.id=bo.id where e.id = ?
Örnek - Join
Bir nesne tipi dönemeyeceği için List<Object> döndürürüz. Şöyle yaparız.
Query("select ...
       from AccountModel acct
         join acct.department dept
         join acct.investigator invest
         join acct.accountCPC acp
       where acct.nInstID= :instId
       order by acct.sclientacctid")
List<Object[]> findByInstId (@Param("instId") Integer instId);
Örnek
Şöyle yaparız
@Repository
public interface EntityExampleRepository extends JpaRepository<EntityExample, String> { boolean existsByValue(final String value); Optional<EntityExample> findByValue(final String value); List<EntityExample> findByName(final String accountHolderName); }
Örnek
Eğer Optional dönüyorsa kullanmak için şöyle yaparız
@Service
public class OrderEventUpdateService {

  @Autowired
  private PurchaseOrderRepository repository;

  @Transactional
  public void updateOrder(final OrchestratorResponseDTO responseDTO){
    this.repository
      .findById(responseDTO.getOrderId())
      .ifPresent(po -> {
        po.setStatus(responseDTO.getStatus());
        this.repository.save(po);
      });
  }
}

Hiç yorum yok:

Yorum Gönder