[내일배움캠프] Spring CRUD

김재진·2025년 12월 29일

내일배움캠프

목록 보기
26/70

1. Spring CRUD 실습

  • Spring에서 3 Layer Architecture 패턴을 기반으로 Create, Read, Update, Delete 기능을 구현하는 실습을 해보았다.

2. Controller

  • 클라이언트로 부터 요청을 Service로 전달한다.
@RestController
@RequiredArgsConstructor
public class MemoController {

    private final MemoService memoService;

	// 메모 작성
    @PostMapping("/memos") // Create
    public ResponseEntity<MemoCreateResponse> create(
            @RequestBody MemoCreateRequest request
    ) {
        return ResponseEntity.status(HttpStatus.CREATED).body(memoService.save(request));
    }
	
    // 메모 조회(전체)
    @GetMapping("/memos") // Read
    public ResponseEntity<List<MemoGetResponse>> getAll() {
        return ResponseEntity.status(HttpStatus.OK).body(memoService.findAll());
    }
	
    // 메모 조회(단건)
    @GetMapping("/memos/{memoId}") // Read
    public ResponseEntity<MemoGetResponse> getOne(
            @PathVariable Long memoId
    ) {
        return ResponseEntity.status(HttpStatus.OK).body(memoService.findOne(memoId));
    }
	
    // 메모 수정
    @PutMapping("/memos/{memoId}") // Update
    public ResponseEntity<MemoUpdateResponse> update(
            @PathVariable Long memoId,
            @RequestBody MemoUpdateRequest request
    ) {
        return ResponseEntity.status(HttpStatus.OK).body(memoService.update(memoId, request));
    }
	
    // 메모 삭제
    @DeleteMapping("/memos/{memoId}") // Delete
    public void delete(
            @PathVariable Long memoId
    ) {
        memoService.delete(memoId);
    }
}

3. Service

  • Controller에서 받은 요청으로 Repository에 접근해서 조회를 한다.
@Service
@RequiredArgsConstructor
public class MemoService {

    private final MemoRepository memoRepository;
	
    
   	// 저장 메서드
    @Transactional
    public MemoCreateResponse save(MemoCreateRequest request) { // MemoCreateResponse라는 dto를 통해 접근  
        Memo memo = new Memo(request.getText()); 
        Memo savedMemo = memoRepository.save(memo);
        return new MemoCreateResponse(
                savedMemo.getId(),
                savedMemo.getText(),
                savedMemo.getCreatedAt(),
                savedMemo.getModifiedAt()
        );
    }
	
    // 조회 메서드 전체
    @Transactional(readOnly = true) // 읽기전용으로 readOnly = true 작성
    public List<MemoGetResponse> findAll() {// 전체 조회이기 때문에 리스트로 조회
        List<Memo> memos = memoRepository.findAll();
        List<MemoGetResponse> dtos = new ArrayList<>();
        for (Memo memo : memos) {
            MemoGetResponse dto = new MemoGetResponse(
                    memo.getId(),
                    memo.getText(),
                    memo.getCreatedAt(),
                    memo.getModifiedAt()
            );
            dtos.add(dto);
        }
        return dtos;
    }
	
    // 조회 메서드 단건
    @Transactional(readOnly = true) 
    public MemoGetResponse findOne(Long memoId) { 
        Memo memo = memoRepository.findById(memoId).orElseThrow( // findById로 Id를 검색함 
                () -> new IllegalStateException("없는 메모입니다.") // 존재 하지 않는 아이디 일 경우 출력
        );
        return new MemoGetResponse(
                memo.getId(),
                memo.getText(),
                memo.getCreatedAt(),
                memo.getModifiedAt()
        );
    }
	// 수정 메서드 
    @Transactional
    public MemoUpdateResponse update(Long memoId, MemoUpdateRequest request) {
        Memo memo = memoRepository.findById(memoId).orElseThrow(
                () -> new IllegalStateException("없는 메모입니다.")
        );
        memo.update(request.getText());
        return new MemoUpdateResponse(
                memo.getId(),
                memo.getText(),
                memo.getCreatedAt(),
                memo.getModifiedAt()
        );
    }
	
    // 삭제 메서드
    @Transactional
    public void delete(Long memoId) { 
        boolean existence = memoRepository.existsById(memoId); // 존재 하는지 참, 거짓 구분
        if(!existence) {
            throw new IllegalStateException("없는 메모입니다."); // 존재하지 않을경우 출력
        }
        memoRepository.deleteById(memoId); // 존재할 경우 삭제
    }
}

4. Repository

  • JpaRepository를 통해서 메서드를 상속받는다
import com.basicmemo.entity.Memo;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemoRepository extends JpaRepository<Memo, Long> {
}

5. 마무리

  • 3 Layer Architecture 패턴을 기반으로 코드를 작성해보았다. 패키지를 나눠서 작성을 해보니 각각 무슨 기능을 하는지 알아보기 쉬웠다.

6. 트러블 슈팅

  • 커밋, 푸쉬를 하는 과정에서 오류가 발생해 github에 코드가 올라가지 않는 오류가 생겼다.
    -> .git 폴더를 삭제해서 기존 git repository와 연결을 끊고 새로운 repository를 생성해서 다시 연결을 하니 제대로 푸쉬가 되었다.
profile
개발공부 처음해보는 사람

0개의 댓글