전체 패키지 구조는 다음과 같다.
다음 8가지 기능을 구현하기 위해 서비스 코드에 메서드 시그니처들을 정리한다.
package todolist.service;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import todolist.dto.TodoRequest;
import todolist.dto.TodoResponse;
import todolist.entity.TodoEntity;
import todolist.repository.TodoRepository;
@Service
@RequiredArgsConstructor
public class TodoService {
private final TodoRepository todoRepository;
@Transactional // 하나의 작업 단위를 명시하기 위한 어노테이션이라는 점이 default. 하나는 성공하고 하나는 실패하는 경우 이 작업이 실패라는 뜻이다.
public TodoResponse create(TodoRequest request) {
TodoEntity instance = new TodoEntity(request.getTitle());
TodoEntity todoEntity = todoRepository.save(instance);
return new TodoResponse(todoEntity);
}
@Transactional
public TodoResponse update(Long id, TodoRequest request) {
// 업데이트 하려는 todo객체 찾기_id 값으로 조회가 되지 않으면 에러를 내보낸다.
TodoEntity todoEntity = todoRepository.findById(id)
.orElseThrow(()-> new IllegalArgumentException("잘못된 입력입니다."));
// 업데이트 한 투두를 담기
TodoEntity updatedTodo = todoEntity.update(request.getTitle());
// 응답하려는 객체에 담아서 반환하기.
return new TodoResponse(updatedTodo);
}
@Transactional
public void delete(Long id) {
todoRepository.deleteById(id);
}
@Transactional
public TodoResponse get(Long id) {
// id 값으로 조회가 되지 않으면 에러를 내보낸다.
TodoEntity todoEntity = todoRepository.findById(id)
.orElseThrow(()-> new IllegalArgumentException("잘못된 입력입니다."));
return new TodoResponse(todoEntity);
}
@Transactional
public Page<TodoResponse> getAll(Pageable pageable) {
// pageable로 todo를 조회
Page<TodoEntity> todoEntities = todoRepository.findAll(pageable);
// entity를 그대로 반환하지 않고 한 번 감싼다.
Page<TodoResponse> todoResponses = todoEntities.map(TodoResponse::new);
return todoResponses;
}
}
package todolist.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import todolist.entity.MemberEntity;
import todolist.repository.MemberRepository;
import java.util.List;
import java.util.Optional;
//@Service
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
// 회원가입
@Transactional
public String join(MemberEntity memberEntity) {
validateDuplicateMember(memberEntity);
memberRepository.save(memberEntity);
return memberEntity.getId();
}
@Transactional
private void validateDuplicateMember(MemberEntity memberEntity) {
memberRepository.findById(memberEntity.getId())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
}
// 회원 조회
@Transactional
public Optional<MemberEntity> findOne(String memberId) {
return memberRepository.findById(memberId);
}
// 전체 회원 조회
@Transactional
public List<MemberEntity> findMembers() {
return memberRepository.findAll();
}
}
package todolist.service;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import todolist.repository.MemberRepository;
import todolist.repository.MemoryMemberRepository;
@Configuration
public class ServiceConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
package todolist.service;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import todolist.entity.MemberEntity;
import todolist.repository.MemberRepository;
import todolist.repository.MemoryMemberRepository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
class MemberServiceTest {
MemberService memberService;
MemberRepository memberRepository;
@BeforeEach
public void beforeEach() {
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
@AfterEach
public void afterEach() {
memberRepository.clearStore();
}
@Test
void 회원가입() {
MemberEntity memberEntity = new MemberEntity();
memberEntity.setId("ohohoh");
memberEntity.setPw("ohoh123");
String saveId = memberService.join(memberEntity);
MemberEntity findMember = memberService.findOne(saveId).get();
assertThat(memberEntity.getId()).isEqualTo(findMember.getId());
}
@Test
public void 중복_회원_예외() {
MemberEntity memberEntity1 = new MemberEntity();
memberEntity1.setId("member1");
memberEntity1.setPw("member123");
MemberEntity memberEntity2 = new MemberEntity();
memberEntity2.setId("member1");
memberEntity2.setPw("member123");
// member1 을 가입시키고
memberService.join(memberEntity1);
// member2 의 중복 여부를 체크
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(memberEntity2));
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
}
}