상태를 변경할 때 사용 → 명령 모델
DAO
리포지터리
- 도메인 중심의 컬렉션 인터페이스
// DAO 스타일
public class MemberDao {
public Member findById(Long id) {
return jdbcTemplate.queryForObject(...);
}
public void save(Member member) {
jdbcTemplate.update(...);
}
}
// Repository 스타일 (Spring Data JPA 기준)
public interface MemberRepository extends JpaRepository<Member, Long> {
Optional<Member> findByEmail(String email);
}
애그리거트가 특정 조건을 충족하는지를 검사
검색 조건을 다양하게 조합해야할 때 사용
public interface Speficiation<T> {
public boolean isSatisfiedBy(T agg);
}
리포지터리에 사용하면 agg는 애그리거트 루트
DAO에 사용하면 agg는 검색 결과로 리턴
public class OrdererldSpec implements Specification<OrderSummary> {
private String ordererld;
public OrdererIdSpec(String ordererld) {
this.ordererld = ordererld;
}
@Override
public Predicate toPredicate(Root<OrderSummary> root,
CriteriaQuery<?> query,
CriteriaBuilder cb) {
return cb.equal(root .get(OrderSummary_.ordererld), ordererld);
}
}
public interface OrderSummaryDao
extends Repository<OrderSummary, String> {
List<OrderSummary> findAll(Specification<OrderSummary> spec);
}
findByOrdererldOrderByOrderDateDescNumberAsc()
List<OrderSummary> findByOrdererId(String ordererld, Sort sort);
List<OrderSummary> findAll(Specification<OrderSummary> spec, Sort sort);
Sort sort = Sort.by("number").ascending();
List<OrderSummary> results = orderSummaryDao.findByOrdererId("userl", sort);
List<MemberData> findFirst3ByNameLike0rderByName(String name)Specification<MemberData> spec = SpecBuilder.builder(MemberData.class)
.ifTrue(earchRequest.isOnlyNotBlocked(),
() -> MemberDataSpecs.nonBlocked())
.ifHasText(searchRequest.getName(),
name -> MemberDataSpecs.nameLike(searchRequest.getName()))
.toSpecQ;
List<MemberData> result = memberDataDao.findAll(spec, PageRequest.of(0, 5));public interface OrderSummaryDao
extends Repository<OrderSummary, String> {
@Query("""
select new com.myshop.order.query.dto.OrderView(
o.number, o.state, m.name, m.id, p.name
)
from Order o join o.orderLines ol. Member m. Product p
where o.orderer.memberld .id = :ordererld
and o.orderer.memberld.id = m.id
and index(ol) = 0
and ol.productld.id = p.id
order by o.number.number desc
"""")
List<OrderView> findOrderView(String ordererld);
}
@Entity
@Immutable
@Subselect(
"""
select o.order_number as number,
o.version, o.orderer_id, o.orderer_name,
o.total_amounts, o.receiver_name, o.state, o.order_date,
p.product_id, p.name as product_name
from purchase_order o inner join order_line ol
on o.order_number = ol.order_number
cross join product p
where
ol.line_idx = 0
and ol.product_id = p.product_id"""
)
뷰처럼 수정 불가능