@Entity
//@Table(name = "item")
public class Item {
//strategy = GenerationType.IDENTITY - pk값을 데이터베이스에서 생성하는 방식
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// length : jpa로 테이블을 생성할 때 컬럼의 길이 값으로 활용
@Column(name = "item_name", length = 10)
private String itemName;
private Integer price;
private Integer quantity;
//JPA는 기본생성자가 필수!!
public Item() {
}
public Item(String itemName, Integer price, Integer quantity) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
}
@Repository
@Transactional
public class JpaItemRepositoryV1 implements ItemRepository {
private final EntityManager em;
public JpaItemRepositoryV1(EntityManager em) {
this.em = em;
}
String jpql = "select i from Item i";
public List<Item> findAll(ItemSearchCond cond) {
// 여기서 Item은 테이블 item이 아니라 객체 Item을 말한다
// Item객체를 가지고 온다
String jpql = "select i from Item i";
Integer maxPrice = cond.getMaxPrice();
String itemName = cond.getItemName();
if (StringUtils.hasText(itemName) || maxPrice != null) {
jpql += " where";
}
boolean andFlag = false;
if (StringUtils.hasText(itemName)) {
jpql += " i.itemName like concat('%',:itemName,'%')";
andFlag = true;
}
if (maxPrice != null) {
if (andFlag) {
jpql += " and";
}
jpql += " i.price <= :maxPrice";
}
log.info("jpql={}", jpql);
TypedQuery<Item> query = em.createQuery(jpql, Item.class);
if (StringUtils.hasText(itemName)) {
query.setParameter("itemName", itemName);
}
if (maxPrice != null) {
query.setParameter("maxPrice", maxPrice);
}
return query.getResultList();
}
// 예시
public interface SpringDataJpaItemRepository extends JpaRepository<Item, Long> {
List<Item> findByItemNameLike(String itemName);
List<Item> findByPriceLessThanEqual(Integer price);
//쿼리 메서드
List<Item> findByItemNameLikeAndPriceLessThanEqual(String itemName, Integer price);
//쿼리 직접 실행
@Query("select i from Item i where i.itemName like :itemName and i.price <= :price")
List<Item> findItems(@Param("itemName") String itemName, @Param("price") Integer price);
}
메소드 이름에는 특정 규칙이 있는데 규칙을 따라 메서드 이름을 지으면 그에 적합한 실제 쿼리문을 작성해준다
하지만 메서드 이름을 보면 너무 복잡하다. 때문에 이런 경우 @Query를 사용하는게 좋다.
jpql문법을 활용하여 쿼리문을 작성하고, 변수(?)부분은 매개변수 부분에 @Param을 사용하여 이름을 일치시켜주면 된다.
@RequiredArgsConstructor
public class JpaItemRepositoryV2 implements ItemRepository {
private final SpringDataJpaItemRepository repository;
그래도 여전히 동적 쿼리 문제는 해결되지 않았다,,,
이를 해결하기 위해 Querydsl이 등판하였다!!