728x90
계층형 구조
controller,web: 웹 계층
service : 비즈니스 로직, 트랜잭션 처리
repository:JPA를 직접 사용하는 계층, 엔티티 매니저 사용
domain: 엔티티가 모여있는 계층, 모든 계층에서 사용
개발 순서 : 서비스 -> 리포지토리 계층을 개발하고 테스트 케이스를 작성해서 검증, 마지막에 웹 계층 적용
MemberRepository와 MemberService 구현
1. MemberRepository
레포지토리 계층에서는 DB저장과 DB에서 조건에 맞는 데이터를 불러오는 기능을 넣어둔다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package com.example.lms_jpa.repository;
import com.example.lms_jpa.domain.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import java.util.List;
@Repository
@RequiredArgsConstructor
public class MemberRepository {
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)
.getResultList();
}
//회원 중복 id검사를 위한 user_id를 가지고
public List<Member> findByMember(String user_id){
return em.createQuery("select m from Member m where m.user_id = :user_id",Member.class)
.setParameter("user_id",user_id)
.getResultList();
}
}
|
cs |
*RequiredArgsConstructor
롬복에서 생성자 주입을 자동으로 해주는 어노테이션이다.
이 어노테이션 없이 직접 생성자 주입을 통해서 구현할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.example.lms_jpa.repository;
import com.example.lms_jpa.domain.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import java.util.List;
@Repository
@RequiredArgsConstructor
public class MemberRepository {
private final EntityManager em;
public MemberRepository(EntityManager em) {
this.em = 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)
.getResultList();
}
//회원 중복 id검사를 위한 user_id를 가지고 찾기
public List<Member> findByMember(String user_id){
return em.createQuery("select m from Member m where m.user_id = :user_id",Member.class)
.setParameter("user_id",user_id)
.getResultList();
}
}
|
cs |
2. MemberService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package com.example.lms_jpa.service;
import com.example.lms_jpa.domain.Member;
import com.example.lms_jpa.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
//회원가입 및 아이디중복검사
public Long join(Member member){
validateDuplicatedMember(member);
memberRepository.save(member);
return member.getId();
}
//
private void validateDuplicatedMember(Member member){
List<Member> findMembers = memberRepository.findByMember(member.getUser_id());
if(!findMembers.isEmpty()){
throw new IllegalStateException("이미 존재하는 회원입니다.");
}
}
//회원 전체조회
public List<Member> findMembers(){
return memberRepository.findAll();
}
//회원 한명 조회
public Member findOne(Long id){
return memberRepository.findOne(id);
}
}
|
cs |
*transactional(readOnly =true)
-> 조회하는 기능은 readOnly로 해서 최적화 가능, transactional의 readOnly 기본값은 false이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.example.lms_jpa.service;
import com.example.lms_jpa.domain.Member;
import com.example.lms_jpa.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
@Transactional
//default값이 false임으로 등록기능에 추가해준다.
public Long join(Member member){
validateDuplicatedMember(member);
memberRepository.save(member);
return member.getId();
}
private void validateDuplicatedMember(Member member){
List<Member> findMembers = memberRepository.findByMember(member.getUser_id());
if(!findMembers.isEmpty()){
throw new IllegalStateException("이미 존재하는 회원입니다.");
}
}
//회원 전체조회
public List<Member> findMembers(){
return memberRepository.findAll();
}
//회원 한명 조회
public Member findOne(Long id){
return memberRepository.findOne(id);
}
}
|
cs |
3. MemberServiceTest
검증할 기능
1) 가입 후 가입한 아이디로 회원 조회가 되는지
2) 가입 시 중복 검사가 제대로 실행되는지
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
package com.example.lms_jpa.service;
import com.example.lms_jpa.domain.Member;
import com.example.lms_jpa.repository.MemberRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
class MemberServiceTest {
@Autowired
MemberRepository memberRepository;
@Autowired
MemberService memberService;
@Test
public void 회원가입() throws Exception{
Member member = new Member();
member.setName("서성우");
member.setUser_id("operstu1");
Long saveIdName = memberService.join(member);
assertEquals(member,memberService.findOne(member.getId()));
}
@Test
public void 중복확인() throws Exception{
Member member1 = new Member();
member1.setUser_id("operstu1");
Member member2 = new Member();
member2.setUser_id("operstu1");
memberService.join(member1);
try{
memberService.join(member2);//예외 터져야 함
}catch(IllegalStateException e){
return;
}
fail("예외가 발생해야합니다!!");
}
}
|
cs |
실행결과
728x90
'프로그래밍 언어 > Spring' 카테고리의 다른 글
<Spring Boot> LMS 프로젝트8. JPA 엔티티 매핑 (0) | 2021.12.09 |
---|---|
<JPA> JPA 2. 엔티티 매핑 (0) | 2021.11.18 |
<JPA> JPA 1. 내부 동작 방식 영속성 (0) | 2021.11.18 |
<Spring> 스프링 핵심원리 - 기본편 후기 (0) | 2021.11.17 |
<Spring>LMS프로젝트7. 학생 출결 로직 작성(5) 컴포넌트스캔과 자동 의존관계 주입 (0) | 2021.11.08 |