ååãN+1åé¡ã解決ããããã«ãJOIN FETCHã䜿ã£ãŠé¢é£ããŒã¿ãäžåºŠã«ååŸããæ¹æ³ãåŠã³ãŸãããããã¯ããã©ãŒãã³ã¹ãã¥ãŒãã³ã°ã®åŒ·åãªãã¯ããã¯ã§ãã
ããããããŒã¿ã倧éã«ååŸããéã«ãããäžã€èæ ®ãã¹ãç¹ããããŸããããã¯ãæ¬åœã«ãã®Entityã®å šãã£ãŒã«ããå¿ èŠãïŒããšããç¹ã§ãã
äŸãã°ããŠãŒã¶ãŒã®ãªã¹ãã衚瀺ããéããã¹ã¯ãŒããæ©å¯æ å ±ãå«ãå šãã£ãŒã«ããååŸããå¿ èŠã¯ãããŸããããIDãšååãšã¡ãŒã«ã¢ãã¬ã¹ãã ãã§ååãªã±ãŒã¹ãã»ãšãã©ã§ãã
ä»åã¯ããã®ããã«å¿ èŠãªãã£ãŒã«ãã ããååŸããã¡ã¢ãªäœ¿çšéããããã¯ãŒã¯è»¢ééãåæžããææ³ã**ãããžã§ã¯ã·ã§ã³ïŒProjectionïŒ**ã«ã€ããŠåŠã³ãŸãã
1. ãããžã§ã¯ã·ã§ã³ãšã¯ïŒ
**ãããžã§ã¯ã·ã§ã³ïŒProjectionïŒ**ãšã¯ãDBããEntityã®å šãã£ãŒã«ãã§ã¯ãªããå¿ èŠãªãã£ãŒã«ãã ããæœåºããŠååŸããããšãæããŸãã
Spring Data JPAã§ã¯ããããžã§ã¯ã·ã§ã³ãå®çŸããããã«ã以äžã®2ã€ã®äž»èŠãªæ¹æ³ãæäŸããŠããŸãã
- ã€ã³ã¿ãŒãã§ãŒã¹ããŒã¹ãããžã§ã¯ã·ã§ã³ïŒInterface-based ProjectionïŒ
- ã¯ã©ã¹ããŒã¹ãããžã§ã¯ã·ã§ã³ïŒClass-based Projection/DTOïŒ
2. ã€ã³ã¿ãŒãã§ãŒã¹ããŒã¹ãããžã§ã¯ã·ã§ã³ïŒæšå¥šïŒ
æãã·ã³ãã«ã§æšå¥šãããæ¹æ³ã§ããååŸããããã£ãŒã«ãåã«å¯Ÿå¿ããGetterã¡ãœãããæã€ã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸ©ããã ãã§ãSpring Data JPAãèªåã§ãã®ã€ã³ã¿ãŒãã§ãŒã¹ãæºãããªããžã§ã¯ããçæããŠãããŸãã
2-1. ãããžã§ã¯ã·ã§ã³çšã€ã³ã¿ãŒãã§ãŒã¹ã®å®çŸ©
äŸãã°ãItem EntityãããååããšãäŸ¡æ Œãã ããååŸãããå ŽåãèããŸãã
Java
// ItemInfo.java: ãããžã§ã¯ã·ã§ã³çšã®ã€ã³ã¿ãŒãã§ãŒã¹
public interface ItemInfo {
// ååŸããããã£ãŒã«ãã«å¯Ÿå¿ããGetterãå®çŸ©ãã
// ãã£ãŒã«ãå㯠get ã®åŸã«ç¶ãååã«å¯Ÿå¿ïŒäŸ: getName -> Item.nameïŒ
String getName();
int getPrice();
// é¢é£ããŒã¿ã®ãã£ãŒã«ããæå®å¯èœ (äŸ: Item.category.name)
String getCategoryName();
}
2-2. Repositoryã§ã®å©çš
Repositoryã€ã³ã¿ãŒãã§ãŒã¹ã®æ€çŽ¢ã¡ãœããã®æ»ãå€ã®åãšããŠãå®çŸ©ãããããžã§ã¯ã·ã§ã³çšã€ã³ã¿ãŒãã§ãŒã¹ãæå®ããŸãã
Java
// ItemRepository.java
import java.util.List;
public interface ItemRepository extends JpaRepository<Item, Long> {
// List<ItemInfo> ãæ»ãå€ã«æå®
// Spring Data JPAã¯ãItem Entityããnameãšpriceã ããæœåºããŠè¿ã
List<ItemInfo> findByName(String name);
}
Serviceå±€ãªã©ã§ãã® findByName ã¡ãœãããåŒã³åºããšãè¿ããããªã¹ãã«ã¯**Item Entityå šäœã§ã¯ãªã**ãItemInfo ã€ã³ã¿ãŒãã§ãŒã¹ãæºãããªããžã§ã¯ãã ããå«ãŸããŸãã
3. ã¯ã©ã¹ããŒã¹ãããžã§ã¯ã·ã§ã³ïŒDTOïŒ
çµæãImmutableïŒäžå€ïŒãª**DTOïŒData Transfer ObjectïŒ**ãšããŠæ±ãããå Žåãããã£ãŒã«ãã«è€éãªããžãã¯ãå ãããå Žåã«å©çšããŸãã
ãã®æ¹æ³ã§ã¯ãååŸããããã£ãŒã«ããæã€å°çšã®ã¯ã©ã¹ïŒDTOïŒãäœæãããã®DTOã®ã³ã³ã¹ãã©ã¯ã¿ãéããŠçµæããããã³ã°ããŸãã
3-1. ãããžã§ã¯ã·ã§ã³çšDTOã®å®çŸ©
DTOã¯ããã¹ãŠã®ãã£ãŒã«ããåŒæ°ã«åãã³ã³ã¹ãã©ã¯ã¿ãæã€å¿ èŠããããŸãã
Java
// ItemSummary.java: ã¯ã©ã¹ããŒã¹ãããžã§ã¯ã·ã§ã³çšã®DTO
import lombok.Value;
// @Value ã¯Lombokã®ã¢ãããŒã·ã§ã³ã§ãfinalãã£ãŒã«ããšãå
šãŠã®åŒæ°ãæã€ã³ã³ã¹ãã©ã¯ã¿ãçæ
@Value
public class ItemSummary {
private Long id;
private String name;
// ãã®ã³ã³ã¹ãã©ã¯ã¿ã§çµæãåãåã
public ItemSummary(Long id, String name) {
this.id = id;
this.name = name;
}
}
3-2. Repositoryã§ã®å©çšïŒJPQLå¿ é ïŒ
ã¯ã©ã¹ããŒã¹ãããžã§ã¯ã·ã§ã³ã䜿ãå ŽåãSpring Data JPAã®èªåã¯ãšãªçææ©èœã¯äœ¿ããã@Query ã¢ãããŒã·ã§ã³ãšJPQLã䜿ã£ãŠæç€ºçã«ãããã³ã°ãæç€ºããå¿ èŠããããŸãã
Java
// ItemRepository.java
import org.springframework.data.jpa.repository.Query;
public interface ItemRepository extends JpaRepository<Item, Long> {
// JPQLã§çµæãDTOã«ãããã³ã°ããããšãæç€ºçã«æå®
// 'new' ããŒã¯ãŒãã®åŸã«ãDTOã®å®å
šä¿®é£Ÿåãšãã³ã³ã¹ãã©ã¯ã¿ã®åŒæ°ãšãªããã£ãŒã«ããæå®ãã
@Query("SELECT new com.example.demo.dto.ItemSummary(i.id, i.name) FROM Item i WHERE i.price < :maxPrice")
List<ItemSummary> findSummaryByPriceLessThan(int maxPrice);
}
ãã®æ¹æ³ã®å©ç¹ã¯ãçµæãäžå€ãªDTOãšããŠè¿ããããããServiceå±€ãControllerå±€ã§å®å šã«ããŒã¿ãå©çšã§ããããšã§ãã
4. ãŸãšãïŒãããžã§ã¯ã·ã§ã³ã®éèŠæ§
ãããžã§ã¯ã·ã§ã³ã¯ãã¢ããªã±ãŒã·ã§ã³ã®å¥å šæ§ãé«ããããã®éèŠãªãã¯ããã¯ã§ãã
- ã»ãã¥ãªãã£: äžèŠãªæ©å¯ããŒã¿ïŒãã¹ã¯ãŒããªã©ïŒããæå³ããServiceå±€ãControllerå±€ã«æµåºããã®ãé²ããŸãã
- ããã©ãŒãã³ã¹: DBããã®ããŒã¿è»¢ééãJPAã«ãããããã³ã°åŠçãã¡ã¢ãªäœ¿çšéãæå°éã«æããç¹ã«å€§èŠæš¡ãªæ€çŽ¢ã«ãããŠå¹æãçºæ®ããŸãã
- 責åã®åé¢: Controllerå±€ã¯ãã¬ãŒã³ããŒã·ã§ã³ã«å¿ èŠãªããŒã¿ïŒDTO/ãããžã§ã¯ã·ã§ã³ïŒã ããæ±ããEntityã®å€æŽã«åœ±é¿ããã«ãããªããŸãã
â æ¬æ¥ã®ãŸãšã
- ãããžã§ã¯ã·ã§ã³ã¯ãEntityã®å šãã£ãŒã«ãã§ã¯ãªããå¿ èŠãªãã£ãŒã«ãã ããååŸããææ³ã§ãããããã©ãŒãã³ã¹åäžãšã»ãã¥ãªãã£åŒ·åã«åœ¹ç«ã€ã
- ã€ã³ã¿ãŒãã§ãŒã¹ããŒã¹ãããžã§ã¯ã·ã§ã³ã¯ãååŸããããã£ãŒã«ãã®Getterãæã€ã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸ©ããã ãã§å®çŸã§ããæãã·ã³ãã«ã§ããïŒæšå¥šïŒã
- ã¯ã©ã¹ããŒã¹ãããžã§ã¯ã·ã§ã³ã¯ãçµæãäžå€ãªDTOãšããŠæ±ãããå Žåã«å©çšããJPQLã® new æ§æãšã³ã³ã¹ãã©ã¯ã¿ãéããŠãããã³ã°ããã
ð æ¬¡åäºå
ããã§ãJPAã䜿ã£ãããŒã¿ã¢ã¯ã»ã¹ïŒCRUDãã«ã¹ã¿ã æ€çŽ¢ããªã¬ãŒã·ã§ã³ããããžã§ã¯ã·ã§ã³ïŒã®äž»èŠãªãã¯ããã¯ã¯ç¶²çŸ ããŸããã
ãããããããã®DBæäœãã·ã¹ãã å ã§æ£ããå®è¡ãããããã«ã¯ããã©ã³ã¶ã¯ã·ã§ã³ãšããä»çµã¿ãå¿ èŠã§ããæ¬¡åã¯ãæ¥ååŠçã®ä¿¡é Œæ§ãä¿èšŒããããã®éèŠãªæŠå¿µã§ããããã©ã³ã¶ã¯ã·ã§ã³ç®¡çãã«ã€ããŠåŠã³ãŸãã
次åïŒã第26åãæ¥åã®ä¿¡é Œæ§ãä¿èšŒïŒããã©ã³ã¶ã¯ã·ã§ã³ç®¡çã®åºæ¬ã ã«ãæåŸ ãã ããïŒ


ã³ã¡ã³ã