스프링의 웹 애플리케이션의 계층구조 쉽게말해서 응답이 들어와서 빠저나가기까지 눈에보이는 폴더의 이동개수가 Controller, Service, Repositort, Domain이 있다.
처음에는 막 객체는 이폴더에, 로직은 저폴더에 생성하며 뭐가뭔지 몰랐지만
이 방식의 장점하나로 BD가 MySQL이든 H2이든 Oracle이든 마음대로 바꿔끼울수 있다는것이다.
하나씩 살펴보자
웹 MVC의 Controller역할이다. 이전의 공부한대로 View에서 핸들러의 흐름을 처리하거나 Model의 데이터를 업데이트 처리하는 로직을 제공한다.
클라이언트의 요청에 대해 Model과 View를 결정하여 전달하는 일종의 조정자로서의 일을 한다.
//이방식이 api방식 페이지에서 {name : 입력한값 } 이런식으로 값이 뜸
@GetMapping("hello-api")
@ResponseBody
public Hello helloApi(@RequestParam("name") String name) {
Hello hello = new Hello();
hello.setName(name);
//이런식으로 만든객체를 json으로 반환하는게 기본 객체가 오면 json으로 만들어서 던지는게 디폴트값
return hello;
}
static class Hello{ //이런 get set을 프로퍼티 접근방식이라고도 함
private String name; //private외부접근불가
public String getName() { //함수로 접근
return name;
}
public void setName(String name) {
this.name = name;
}
}
이런식으로 @GetMapping("hello-api")
요청이 오면
return hello;
나가는 방식을 정해준다.
Service의 역할은 DB에서 받아온 데이터를 전달받아 가공하는 것이다.
비즈니스로직과 트랜잭션 처리를 담당한다.
public Long join(Member member) {
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
}
회원을 추가하고 추가할때 이미 존재하는 회원인지 확인하는 두 함수이다.
이런식으로 비즈니스로직을 담당한다.
데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리하는 곳이다.
@Override
public Optional<Member> findByName(String name) {
List<Member> result = jdbcTemplate.query("select * from member where name = ?", memberRowMapper(), name);
return result.stream().findAny();
}
spring data jpa를 사용하면 워낙 간단해지기에 jdbc의 DB에서 name
을 찾는 한부분을 가져왔다.
쿼리로 SQL문 그대로 select
, from
, where
사용하여 데이터를 뽑아 spring안으로 가져오는것이다.
이런역할만 있는곳이 Repository이다.
데이터가 요청으로 들어오면 Controller,Service,Repository 이곳저곳 옴겨다니며 주어진 가공처리를 할건데 이 이동에서 어떤 상자에 담겨서 이동될것인가? 하는것이다.
마트에서 모두 똑같은 쇼핑카드에 짐을 옮기는 처럼 그 기준처럼 느껴진다.
엔티티가 모여 있는 계층이라고 한다.
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
정말로 데이터가 담길 class
딱 그정도이다.
이전까지 해온 개발은 사실상 Controller,Service,Repository,Domain모두 하나로 묶어서 개발한것과 같다.
이상황에서 자료와 객체가 섞이고 유지보수도 힘들고 했는데 Clean Architecture의 중요성을 점점 느끼고있다.