-
Notifications
You must be signed in to change notification settings - Fork 0
JPA Section5‐6
SH-Seol edited this page May 25, 2024
·
1 revision
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class ItemService {
private final ItemRepository itemRepository;
@Transactional
public void saveItem(Item item){
itemRepository.save(item);
}
public List<Item> findItems(){
return itemRepository.findAll();
}
public Item findOne(Long itemId){
return itemRepository.findOne(itemId);
}
5-6
- saveItem은 반드시 Transactional을 해야하는 것 잊지 말자. 안그러면 저장 안된다!
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class OrderService {
private final OrderRepository orderRepository;
private final MemberRepository memberRepository;
private final ItemRepository itemRepository;
/**
* 주문
*/
@Transactional
public Long order(Long memberId, Long itemId, int count){
Member member = memberRepository.findOne(memberId);
Item item = itemRepository.findOne(itemId);
Delivery delivery = new Delivery();
delivery.setAddress(member.getAddress());
OrderItem orderItem = OrderItem.createOrderItem(item, item.getPrice(), count);
//1. OrderItem orderItem1 = new OrderItem();
//OrderItem1.setCount();
Order order = Order.createOrder(member, delivery, orderItem);
//주문 저장
orderRepository.save(order);
return order.getId();
}
}
-
1번이 안되는 이유는 퍼져 있다 보니, 나중에 유지보수가 매우 어려워짐.
- 막는방법: protected 생성자
- Or OrderItem, Order에@NoArgsConstructor(access=AccessLevel.PROTECTED)
-
엔티티가 비즈니스 로직을 가지고 객체 지향의 특성을 적극 활용하는 것 → 도메인 모델 패턴
-
엔티티에 비즈니스 로직이 거의 없고 서비스 계층에서 대부분의 비즈니스 로직을 처리하는 것 → 트랜잭션 스크립트 패턴
-
한 프로젝트 안에서 둘 다 같이 사용될 수 있음. 문맥에 따라 선택
-
test는 단위테스트가 정말 좋은 테스트.
방법 1
String jpql = "select o from Order o join o.member m";
boolean isFirstCondition = true;
if(orderSearch.getOrderStatus() != null){
if(isFirstCondition){
jpql += "where";
isFirstCondition = false;
}else{
jpql += "and";
}jpql += "o.status = :status";
}
if (StringUtils.hasText(orderSearch.getMemberName())){
if (isFirstCondition){
jpql += "where";
isFirstCondition = false;
}else{
jpql += "and";
}
jpql += "m.name like :name";
}
TypedQuery<Order> query = em.createQuery(jpql, Order.class)
.setMaxResults(1000);
if(orderSearch.getOrderStatus() != null){
query = query.setParameter("status", orderSearch.getOrderStatus());
}
if(StringUtils.hasText(orderSearch.getMemberName())){
query = query.setParameter("name", orderSearch.getMemberName());
}
return query.getResultList();
- 버그가 가득
방법2
public List<Order> findAllByCriteria(OrderSearch orderSearch){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
Root<Order> o = cq.from(Order.class);
Join<Object, Object> m = o.join("member", JoinType.INNER);
List<Predicate> criteria = new ArrayList<>();
if(orderSearch.getOrderStatus()!= null){
Predicate status = cb.equal(o.get("status"), orderSearch.getOrderStatus());
criteria.add(status);
}
if (StringUtils.hasText(orderSearch.getMemberName())){
Predicate name =
cb.like(m.<String>get("name"), "%" + orderSearch.getMemberName() + "%");
criteria.add(name);
}
cq.where(cb.and(criteria.toArray(new Predicate[criteria.size()])));
TypedQuery<Order> query = em.createQuery(cq).setMaxResults(1000);
return query.getResultList();
- 이건 사람이 유지보수 할 수 없다.
방법3(Querydsl)