Controller 하나만으로 클라이언트의 요청을 처리하기에는 Controller 의 코드의 길이가 너무 길어지고 코드의 가독성이 낮아진다는 단점이 있다.
=> 위와 같은 문제를 해결하기 위해 처리과정을 아래와 같은 3개로 나눔
Controller , Service, Repository 로 분리함

- 클라이언트의 요청을 받는다.
- 요청에 대한 로직 처리는 Service 에 전달한다.
- 나중에 처리가 완료되고 나면 완료된 결과를 클라이언트에게 응답한다.

- 사용자의 요구사항을 처리하는 제일 중요한 부분 (비즈니스 로직 처리)
- 제일 비대해지고 있는 코드
- DB 저장 및 조회가 필요할 때는 Repository 에게 요청

- DB와 가장 가까이서 DB를 관리하는 역할을 한다. (연결, 해제, 자원관리)
- DB CRUD 작업을 처리

=> 정리하면 위와 같다.
@PostMapping("/memos")
public MemoResponseDto createMemo(@RequestBody MemoRequestDto requestDto) {
// RequestDto -> Entity
Memo memo = new Memo(requestDto);
// DB 저장
KeyHolder keyHolder = new GeneratedKeyHolder(); // 기본 키를 반환받기 위한 객체
String sql = "INSERT INTO memo (username, contents) VALUES (?, ?)";
jdbcTemplate.update( con -> {
PreparedStatement preparedStatement = con.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS);
preparedStatement.setString(1, memo.getUsername());
// 첫번째 ? 에 대입할 것
preparedStatement.setString(2, memo.getContents());
// 두번째 ? 에 대입할 것
return preparedStatement;
},
keyHolder);
// DB Insert 후 받아온 기본키 확인
Long id = keyHolder.getKey().longValue();
memo.setId(id);
// Entity -> ResponseDto
MemoResponseDto memoResponseDto = new MemoResponseDto(memo);
return memoResponseDto;
}
기존의 POST 요청이 오면 body의 내용을 가지고 jdbc 를 통해 db에 저장하는 코드이다. 좀 길고 읽기 쉽지 않은편 그러나 동작은 잘 한다.
// 메모 추가
@PostMapping("/memos")
public MemoResponseDto createMemo(@RequestBody MemoRequestDto requestDto) {
MemoService memoService = new MemoService(jdbcTemplate);
return memoService.createMemo(requestDto); // 컨트롤러와 서비스의 이름을 일치 시키면 좋다.
}
위 코드에 비해 정말 간결해진 것을 확인 할 수 있다.
public MemoResponseDto createMemo(MemoRequestDto requestDto) {
// RequestDto -> Entity
Memo memo = new Memo(requestDto);
MemoRepository memoRepository = new MemoRepository(jdbcTemplate);
Memo saveMemo =memoRepository.save(memo); // db 저장
// Entity -> ResponseDto
MemoResponseDto memoResponseDto = new MemoResponseDto(saveMemo);
return memoResponseDto;
// 위 세줄을 아래 한줄로 줄일 수 있다. (saveMemo 인스턴스를 안쓸것이라면)
// return new MemoResponseDto(memoRepository.save(memo));
}
컨트롤러에서 분리된 코드의 일부이다. 인자로 받아온
requestDto를 통해Memo엔티티 인스턴스를 생성하고 해당 인스턴스를 db와 연결된repository로 일을 위임한다.
public Memo save(Memo memo) {
// DB 저장
KeyHolder keyHolder = new GeneratedKeyHolder(); // 기본 키를 반환받기 위한 객체
String sql = "INSERT INTO memo (username, contents) VALUES (?, ?)";
jdbcTemplate.update(con -> {
PreparedStatement preparedStatement = con.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS);
preparedStatement.setString(1, memo.getUsername());
// 첫번째 ? 에 대입할 것
preparedStatement.setString(2, memo.getContents());
// 두번째 ? 에 대입할 것
return preparedStatement;
},
keyHolder);
// DB Insert 후 받아온 기본키 확인
// 아래 코드가 없어도 정상적으로 저장은 되지만 엔티티에 id 값을 주고 요청의 응답으로 반환하기 위해 사용
Long id = keyHolder.getKey().longValue();
memo.setId(id);
return memo;
}
Repository 가 길다고 생각하지마라!! 나중에 jpa를 사용한다면 이코드는 거의 사라지다 싶이 한다.

이전과 동일하게 CRUD 동작이 정상적으로 동작한다.
(지금은 이런 분리가 정말 편한건지 알 수 없으나 나중에는 Repository 코드가 JPA 덕분에 훨씬 간결해 질 수 있고 또한 나중에 수정요청이 들어오면 모듈화가 되어 있기 때문에 특정 부분만 수정하면 되는 장점이 존재한다.)