애플리케이션 아키텍처
계층형 구조 사용
- controller, web: 웹 계층
- service: 비즈니스 로직, 트랜잭션 처리
- repository: JPA를 직접 사용하는 계층, 엔티티 매니저 사용
- domain: 엔티티가 모여 있는 계층, 모든 계층에서 사용
패키지 구조
- jpabook.jpashop
- domain
- exception
- repository
- service
- web
Repository
//ex) MemberRepository
@Repository // spring bean으로 자동 등록됨
@RequiredArgsConstructor // final 있는 필드만 가지고 생성자 만들어 줌
public class MemberRepository {
//@PersistenceContext spring이 엔티티 매니저를 만들어 주입 -> @RequiredArgsConstructor로 대체
private final EntityManager em;
public void save(Member member) {
em.persist(member);
}
public Member findOne(Long id) {
return em.find(Member.class, id);
}
public List<Member> findAll() {
return em.createQuery("select m from Member m", Member.class) // from의 대상이 테이블이 아닌 엔티티
.getResultList();
}
}
Service
//ex) MemberService
@Service
@Transactional(readOnly = true) // 모든 데이터 변경이나 로직들은 트랜잭션 안에서 수행 쓰기는 -> Transactional
//@AllArgsConstructor // 필드를 가지고 생성자를 만들어 줌
@RequiredArgsConstructor // final 있는 필드만 가지고 생성자 만들어 줌
public class MemberService {
//@Autowired -> @RequiredArgsConstructor로 대체
private final MemberRepository memberRepository;
/**
* 회원 가입
*/
@Transactional
public Long join(Member member) {
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}
/**
* 회원 전체 조회
*/
public List<Member> findMembers() {
return memberRepository.findAll();
}
}
Test
public class MemberService 에서 Ctrl + Shift + T 로 MemberServiceTest class 만들기
//ex) MemberServiceTest
@RunWith(SpringRunner.class) //junit 실행시 spring과 엮여서 실행
@SpringBootTest // springboot 띄운 상태로 테스트
@Transactional // 트랜잭션 걸고 테스트 후 롤백
public class MemberServiceTest {
@Autowired MemberService memberService;
@Autowired MemberRepository memberRepository;
@Test
public void 회원가입() throws Exception {
//given
Member member = new Member();
member.setName("kim");
//when
Long savedId = memberService.join(member);
//then
assertEquals("회원가입한 멤버와 같아야한다.", member, memberRepository.findOne(savedId));
}
@Test(expected = IllegalStateException.class)
public void 중복_회원_예외() throws Exception {
//given
Member member1 = new Member();
member1.setName("kim");
Member member2 = new Member();
member2.setName("kim");
//when
memberService.join(member1);
memberService.join(member2); // 예외 발생
//then
fail("예외가 발생해야 한다.");
}
}
test/resources/application.yml 생성 -> test는 resources/application.yml이 우선권을 가짐
메모리 DB로 실행 가능 -> 별도 DB 필요 x
(ddl-auto 도 create-drop 모드로 동작)
JPA는 데이터를 변경한 다음에 update query 직접 짜서 올릴 필요가 없다!
JPA를 이용하면 바뀐 변경 포인트들을 찾아 데이터베이스에 업데이트 쿼리 날려줌
도메인 모델 패턴
- 엔티티가 비즈니스 로직을 가지고 객체 지향의 특성을 적극 활용하는 것
트랜잭션 스크립트 패턴
- 엔티티에는 비즈니스 로직이 거의 없고 서비스 계층에서 대부분의 비즈니스 로직을 처리하는 것
Ctrl + Alt + m : 해당 코드로 새로운 메소드 생성
Ctrl + B, Ctrl + Alt + <- : 사용 위치 검색
Ctrl + Alt + P : 함수 내의 값 파라미터로 꺼내기
주문 검색 기능 개발
JPA에서 동적 쿼리를 어떻게 해결해야 하는가?
-> Querydsl
참고 강의 :
실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 - 인프런 | 강의
실무에 가까운 예제로, 스프링 부트와 JPA를 활용해서 웹 애플리케이션을 설계하고 개발합니다. 이 과정을 통해 스프링 부트와 JPA를 실무에서 어떻게 활용해야 하는지 이해할 수 있습니다., - 강
www.inflearn.com
'JPA > 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발' 카테고리의 다른 글
[스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발] 7. 웹 계층 개발 (0) | 2023.01.06 |
---|---|
[스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발] 2. 도메인 분석 설계 (0) | 2023.01.03 |
[스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발] 1. 프로젝트 환경설정 (0) | 2023.01.02 |