저장: jpa.persist(member)
조회: jpa.find(memberId)
수정: member.setName("변경할 이름")
삭제: jpa.remove(member)
사용자쿼리: TypeQuery<Product> query = jpa.createQuery("select p from Product as p", Product.class) //타입 명확할 때는 타입지정한 변수로 받거나 TypeQuery
Query query = jpa.createQuery("select p.id, p.name from Product as p") //타입 지정 불가일 때 Query
Product result = query.getSingleResult() //결과가 하나일 때
List<Product> result = query.getResultList() //결과가 하나 이상일 때 (결과없으면 빈 리스트)
@Entity: 엔티티 지정
@Table: Table명 지정
@Builder: 빌더 자동 생성
@Getter: getter 자동 생성
@Setter: setter 자동 생성
@Id: 기본키 지정
@GeneratedValue(strategy = GenerationType.xx): 값 자동 생성
@Column(): 컬럼에다 지정
@CreatedDate: type이 시간일 때 사용 생성 시간값 할당
@JoinColumn : 다른 entity와 외래키 지정. @Column처럼 ()안에 설정 가능
@ManyToOne: 다대일 (본 엔티티가 다) ex.Product
@OneToMany: 일대다 (본 엔티티가 일) ex.Category
@OneToOne: 일대일
@ManyToMany: 다대다. 실무에서 쓰는 것 비추
@ManyToOne(targetEntity = Category.class, fetch = FetchType.LAZY) // LAZY는 영속성관련. 지연로딩
@JoinColumn(name="type", nullable=false)
private Category category // Category 엔티티의 type과 외래키로 사용
@ManyToOne(targetEntity = Category.class, fetch = FetchType.LAZY) //LAZY: JPA 영속성,값을 꺼내쓸 때 얘를 조인해줘
@JoinColumn(name = "type", nullable = false)
private Category category;
TIP: @ManyToOne, @OneToOne은 기본이 즉시 로딩이니 LAZY 설정을 필수적으로 하자@OneToMany(mappedBy="category", cascade=CascadeType.PERSIST, orphanRemoval = true)
private List<Product> products;
String query = "select m from Member m where m = :member";
List<Team> result = em.createQuery(query, Member.class)
.setParameter("member", member1)
.getResultList();
String query = "select m from Member m order by m.name desc";
List<Member> result = em.createQuery(query, Member.class)
.setFirstResult(10)
.setMaxResult(20)
.getResultList();
public interface AccountRepository extends JpaRepository<Account, Long> {
Optional<Account> findByEmail(String email);
Optional<Account> findByNickname(String nickname);
}
https://velog.io/@kku64r/mapstruct
필터링을 할 때 쓰기에 좋다고 생각했다.
하지만 JPA/김영한님의 강의에서 매우 비추천
을 하셨고, 앞으로 사용 안 할 예정이다.
그러니 쿼리DSL을 쓰자!
CasesSpecification.java
package com.service.domain.product.service.specification;
import com.service.domain.product.entity.Cases;
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
public class CasesSpecification {
public static Specification<Cases> containsName(String name) {
return (root, query, criteriaBuilder) -> criteriaBuilder.like(root.get("name"), "%"+name+"%");
} // 이름 포함 검색
public static Specification<Cases> equalCorp(List<String> corp) {
return (root, query, criteriaBuilder) -> root.get("corp").in(corp);
} // 회사 동일 검색
public static Predicate equalExtendedAtx(CriteriaBuilder cb, Root root, boolean extendedAtx) {
return cb.equal(root.get("extendedAtx"), extendedAtx);
} // extendedAtx 동일 검색(predicate. spec으로 변환 필요)
public static Specification<Cases> betweenPrice(int minPrice, int maxPrice) {
return (root, query, criteriaBuilder) -> criteriaBuilder.between(root.get("price"), minPrice, maxPrice);
} //가격 사이 검색
public static Specification<Cases> result(Predicate p) {
return (root, query, criteriaBuilder) -> p;
} // Predicate -> Specification
}
ProductServiceImpl.java의 getCaseList() 메소드
@Override
public ProductListDto getCasesList(CasesRequest request, int page, int desc) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Cases> criteriaQuery = cb.createQuery(Cases.class);
Root<Cases> itemRoot = (Root<Cases>) criteriaQuery.from(Cases.class).alias("generatedAlias0"); //별칭해줘야함
Predicate p = null;
Specification<Cases> spec = (root, query, criteriaBuilder) -> null;
if (request.getName() != null) {
spec = spec.and(CasesSpecification.containsName(request.getName()));
}
if (request.getCorp() != null && request.getCorp().size() > 0) {
spec = spec.and(CasesSpecification.equalCorp(request.getCorp()));
}
if (request.isExtendedAtx()) { //or이라서 Predicate로 만들고 후에 spec에 포함
if (p == null)
p = CasesSpecification.equalExtendedAtx(cb, itemRoot, true);
else
p = cb.or(p, CasesSpecification.equalExtendedAtx(cb, itemRoot, true));
}
if (request.getPrice() != null && request.getPrice().size() > 1) {
spec = spec.and(CasesSpecification.betweenPrice(request.getPrice().get(0), request.getPrice().get(1)));
}
if (p != null)
spec = spec.and(CasesSpecification.result(p)); //Predicate를 Spec에 포함
//페이지네이션
Pageable pageable = getPageable(page, desc);
Page<Cases> pageCasess = casesRepository.findAll(spec, pageable);
List<Cases> casess = pageCasess.getContent();
int totalPages = pageCasess.getTotalPages();
~~~
~~~
return ProductListDto.builder()
.productDtoList(list)
.totalPage(totalPages)
.build();
}
...지금봐도 복잡하다. And와 Or 같이 있을 때 특히 힘들다. 쓰지말자. 쿼리DSL쓰자.
spec 참조글 추천 https://jforj.tistory.com/95
추후 정리