Giriş
Şu satırı dahil ederiz
Şu satırı dahil ederiz
import org.springframework.data.jpa.repository.EntityGraph;
Açıklaması şöyle.
There are two types of entityGraphs, Fetch and Load, which defines if the entities not specified by attributeNodes of entityGraphs should be fetched lazily or eagerly. Attributes specified by attributeNodes of entityGraph are always fetched eagerly.FETCH TYPE: Attributes that are specified by attributeNodes of entityGraph are treated as FetchType.EAGER and rest of the attributes are treated as FetchType.Lazy.LOAD TYPE: Attributes that are specified by attributeNodes of entityGraph are treated as FetchType.EAGER and rest of the attributes are treated according to their specified or default fetchTypes.
Bu bu anotasyon
1. @NamedEntityGraph ile ilişkilendirilebilir
@NamedEntityGraph.attributeNodes ile belirtilen alanlar FETCH veya LOAD olarak şekilde yüklenir. @EntityGraph.value alanı kullanılacak @NamedEntityGraph anotasyonunu belirtir.
2. Tek başına kullanılabilir - Ad-hoc
Bu durumda yüklenecek alanlar belirtmek gerekir. @EntityGraph.attributePaths şeklinde belirtilebilir.
3. @NamedEntityGraph İle Birlikte Kullanım
3.1 FETCH Kullanımı
Varsayılan type FETCH.
@EntityGraph.type FETCH + @NamedEntityGraph Kullanımı yazısına taşıdım
Yani @NamedEntityGraph.attributeNodes anotasyonu ile belirtilenler EAGER yüklenir. Geri kalan her şey LAZY yüklenir.
3.2 LOAD Kullanımı
Açıklaması şöyle.
... attributes that are specified by attribute nodes of the entity graph are treated as FetchType.EAGER and attributes that are not specified are treated according to their specified or default FetchType.
Örnek - @NamedEntityGraph.attributeNodes
@Entity
@Table(name = "books", schema = Constants.BENCHMARKS)
@NamedEntityGraph(name = "BookEntity.all",attributeNodes = @NamedAttributeNode("aliases"))
public class BookEntity {
@Id
private String isbn = UUID.randomUUID().toString();
@Column(name = "title")
private String title;
@Column(name = "description")
private String description;
@CollectionTable(schema = Constants.BENCHMARKS, name = "book_tags",
joinColumns = @JoinColumn(name = "book_isbn"))
@ElementCollection(fetch = FetchType.EAGER)
private List<String> aliases;
}
Kullanmak için @EntityGraph gerekir. Şöyle yaparız@EntityGraph(value = "BookEntity.all", type = EntityGraphType.LOAD)
@Query("SELECT x FROM BookEntity x " +
"WHERE x IN (" +
" SELECT y FROM BookEntity y" +
" INNER JOIN y.aliases yt" +
" WHERE yt IN (" +
" :aliases" +
" )" +
" GROUP BY y" +
" HAVING COUNT( DISTINCT yt) = (" +
" :aliasesSize)" +
" )")
Iterable<BookEntity> findAllByAliasesContainsAll(@Param("aliases") Collection<String>
aliases, @Param("aliasesSize") long aliasesSize);
Örnek
Elimizde şöyle bir kod olsun.
@Entity
@Table(name = "books", schema = Constants.BENCHMARKS)
@NamedEntityGraph(name = "BookEntity.all",attributeNodes = @NamedAttributeNode("aliases"))
public class BookEntity {
@Id
private String isbn = UUID.randomUUID().toString();
@Column(name = "title")
private String title;
@Column(name = "description")
private String description;
@CollectionTable(schema = Constants.BENCHMARKS, name = "book_tags",
joinColumns = @JoinColumn(name = "book_isbn"))
@ElementCollection(fetch = FetchType.EAGER)
private List<String> aliases;
}
Repository sınıfında @NamedEntity anotasyonunu kullanmak için şöyle yaparız.@EntityGraph(value = "BookEntity.all", type = EntityGraphType.LOAD)
@Query("select b from BookEntity b where ...")
Iterable<BookEntity> findAllByAliasesContainsAll(@Param("aliases")
List<String> aliases);
4. Tek Başına Kullanım - Ad-hocÖrnek
Eğer @NamedEntityGraph kullanmak istemiyorsak şöyle yaparız. Burada @EntityGraph.attributePaths kullanılıyor
public interface PublicationRepository extends JpaRepository<Publication,String> { @EntityGraph(type = EntityGraph.EntityGraphType.FETCH, attributePaths = "articles") List<Publication> findByCategory(String category); }
Çıkan SQL şöyledir
SELECT * FROM publication LEFT OUTER JOIN article ON publication.publication_id = article.publication_id WHERE publication.category = 'technology'
Örnek
Şöyle yaparız. Burada aslında hem tek başına kullanım hem de @NamedEntityGraph gösteriliyor.
public interface PostRepository extends JpaRepository<Post,Long> {// referencing a named entity graph@EntityGraph(value = "post-entity-graph", type = EntityGraph.EntityGraphType.LOAD)Optional<Post> findById(Long id);// ad-hoc entity graph@EntityGraph(attributePaths = { "subject","user" })List<Post> getAllByUserId(Long id);}
Örnek
Şöyle yaparız
Üretilen SQL şöyle@Repositorypublic interface UserDetailsRepository extends JpaRepository<UserDetails, String> {// ad-hoc entity graph@EntityGraph(type = EntityGraph.EntityGraphType.FETCH, attributePaths = "addresses")List<UserDetails> findByContainingName(String text);}
SELECT userdetail0_.id as id1_1_0_, addresses1_.id as id1_0_1_, ...FROM user_details userdetail0_LEFT OUTER JOIN address addresses1_ ONuserdetail0_.id=addresses1_.user_id WHERE userdetail0_.name LIKE ? ESCAPE ?
Aynı şeyi @NamedEntityGraph ile şöyle yapardık
@Entity@Table(name = "user_details")@Getter@Setter@NamedEntityGraph(name="user_details_entity_graph",
attributes= @NamedAttributedNode({"addresses"})public class UserDetails {...@OneToMany(cascade = CascadeType.ALL, mappedBy = "userDetails")private List<Address> addresses;}@Repositorypublic interface UserDetailsRepository extends JpaRepository<UserDetails, String> {@EntityGraph(type = EntityGraph.EntityGraphType.FETCH,
value="user_details_entity_graph")List<UserDetails> findByContainingName(String text);}
Hiç yorum yok:
Yorum Gönder