[SPRING] 기본 어노테이션 정리
코딩 자율학습 스프링부트3
올해 1월 쯤에 백엔드 공부를 해보겠다고 구매해서 방학 내에 다 못 끝냈었다. 3학년 1학기 동안 UMC를 활동하면서 스프링에 대해서 어느정도 학습을 진행했다. 학기중에 학습했던 스프링 개념들을 이 책을 통해 다시 한 번 탄탄하게 정리하고 싶다는 생각에 7월동안 다시 이 책을 펼치게 되었다. 지금부터는 이 책에서 학습한 어노테이션들을 코드와 함께 정리해보려 한다. 뿐만 아니라 꼭 기억하고 싶은 내용을 추가로 정리할 예정이다.
코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문 | 홍팍 - 교보문고
코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문 | 스프링 부트 백엔드 개발, 실습 문턱을 낮추고 자신 있게 시작하자!스프링 부트를 처음 접하는 입문자와 이미 공부했지만 부족하다고 느끼
product.kyobobook.co.kr
기본 어노테이션
@Entity
해당 클래스가 엔티티임을 선언한다. 클래스의 필드를 바탕으로 DB에 테이블을 생성한다.
@Id
엔티티의 대표키로 지정한다.
@GeneratedValue(strategy=GenerationType.IDENTITY)
기본키 생성을 DB에게 위임하는 방식으로, id값을 따로 할당하지 않아도 DB가 자동으로 생성한다.
@Column
JPA에서 제공하는 어노테이션으로, 이를 부여받은 클래스를 기반으로 DB 속 테이블이 생성된다.
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private Long age;
}
롬복 관련 어노테이션
롬복이란 코드를 간소화해주는 라이브러리이다.
getter(), setter(), constructor(), toString()과 같은 필수 메서드를 어노테이션 하나로 간소화할 수 있게 도와준다.
코드 반복 최소화 뿐만 아니라 로깅 기능도 지원한다.
@Getter
각 필드 값을 조회할 수 있는 getter 메서드를 자동으로 생성한다.
@ToString
모든 필드를 출력할 수 있는 toString 메서드를 자동으로 생성한다.
@NoArgsConstructor
매개변수가 아예 없는 기본 생성자를 자동으로 생성한다.
@AllArgsConstructor
모든 필드를 매개변수로 갖는 생성자를 자동으로 생성한다.
@Entity
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String title;
@Column
private String content;
}
@Slf4j
Simple Logging Facade for Java의 약자로, 주로 로깅할 때 사용한다.
로깅 기능으로 로그를 찍으면 나중에라도 그동안 찍힌 로그를 찾을 수 있다. 로그를 찍을 때는 log,info()문 사용한다.
@Slf4j // 로깅 기능을 위한 어노테이션 추가
@Controller
public class ArticleController {
@Autowired // 스프링 부트가 미리 생성해 놓은 리파지터리 객체 주입(DI)
private ArticleRepository articleRepository;
@PostMapping("/articles/create")
public String createArticle(ArticleForm form) {
log.info(form.toString());
// 1. DTO를 엔티티로 변환
Article article = form.toEntity();
log.info(article.toString());
// 2. 리파지터리로 엔티티를 DB에 저장
Article saved = articleRepository.save(article);
log.info(saved.toString());
return "redirect:/articles/" + saved.getId();
}
}
RestController에서 사용되는 어노테이션
@RestController
해당 클래스가 RestController임을 선언하는 어노테이션이다.
@RestController는 @Controller에 @ResponseBody가 추가된 어노테이션으로, 주로 JSON 형태로 객체 데이터가 반환된다.
REST Controller의 특징
클라이언트의 데이터 조회, 생성, 수정, 삭제 요청을 HTTP 메서드에 맞게 받아 처리한다.
HTTP 메서드에따라 @GetMapping, @PostMapping, @PatchMapping, @DeleteMapping 등의 어노테이션이 존재한다.
@Autowired
스프링부트가 미리 생성해 놓은 리파지터리 객체 주입(DI)하는 어노테이션이다.
의존성 주입(Dependency Injection : DI)은 외부에서 만들어진 객체를 필요한 곳으로 가져오는 기법이다.
@PathVariable
URL 요청으로 들어온 전달값을 컨트롤러의 매개변수로 가져오는 어노테이션이다.
@RequestBody
클라이언트 측에서 JSON 데이터를 요청 본문에 담아 서버로 보내면, 서버에서는 @RequestBody 어노테이션을 사용해 HTTP 요청 본문에 담긴 값들을 자바 객체로 변환해 저장한다.
@RestController
public class ArticleApiController {
@Autowired
private ArticleService articleService;
// 단일 article 조회
@GetMapping("/api/articles/{id}")
public Article show(@PathVariable Long id){
return articleService.show(id);
}
// POST
@PostMapping("/api/articles")
public ResponseEntity<Article> create(@RequestBody ArticleForm dto){
Article created = articleService.create(dto);
return (created != null) ?
ResponseEntity.status(HttpStatus.OK).body(created) :
ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
}
Service에서 사용하는 어노테이션
@Service
해당 어노테이션이 선언된 클래스를 서비스로 인식해 서비스 객체를 생성합니다. 컨트롤러는 객체 주입하는 방식으로 서비스 객체를 사용할 수 있다.
@Transactional
메서드가 진행되다가 중간에 실패를 하더라도 롤백을 통해 이전 상태로 돌아갈 수 있다.
즉, 처음부터 끝까지 완전히 실행되거나 아예 실행되지 않거나 둘 중 하나로 동작한다.
@Service
public class ArticleService {
@Autowired
private ArticleRepository articleRepository;
@Transactional
public List<Article> createArticles(List<ArticleForm> dtos) {
// 1. dto 묶음을 엔티티 묶음으로 변환하기
List<Article> articleList = dtos.stream()
.map(dto -> dto.toEntity())
.collect(Collectors.toList());
// 2. 엔티티 묶음을 DB에 저장하기
articleList.stream()
.forEach(article -> articleRepository.save(article));
// 3. 강제 예외 발생시키기
articleRepository.findById(-1L).orElseThrow(() -> new IllegalArgumentException("결제 실패!"));
// 4. 결과 값 반환하기
return articleList;
}
}
API란?
application programming interface의 약자로, 애플리케이션을 간편하게 사용할 수 있게 하는, 미리 정해진 일종의 약속으로 사용자와 프로그램 간 상호 작용을 돕는다. 예를 들면, 자판기의 버튼 하나하나가 api가 된다. 환타 버튼을 누르면 환타가, 밀키스 버튼을 누르면 밀키스가 나오는 것처럼, 각 버튼에 따라 반환될 음료를 미리 약속해놓은 것이다.
Rest API는 클라이언트와 서버 사이의 상호작용, 즉 HTTP 요청에 따른 JSON 응답에 대한 약속인 셈이다.
스트림 문법이란?
스트림(stream) 문법은 리스트와 같은 자료구조에 저장된 요소를 하나씩 순회하면서 처리하는 코드 패턴이다.
예시 #1
이러한 코드를
for(int i=0; i<articleList.size(); i++){
Article article = articleList.get(i);
articleRepository.save(article);
}
이렇게 간단하게 작성 가능하다.
articleList.stream()
.forEach(article -> articleRepository.save(article));
예시 #2
또한 for문으로 작성된 긴 코드를
List<Article> articleList = new ArrayList<>();
for(int i=0; i<dtos.size(); i++){
ArticleForm dto = dtos.get(i);
Article entity = dto.toEntity();
articleList.add(entity);
}
스트림 문법으로 작성하면 3줄로 줄일 수 있다.
List<Article> articleList = dtos.stream()
.map(dto -> dto.toEntity())
.collect(Collectors.toList());
.stream 은 dto라는 리스트를 스트림화하겠다는 의미이고,
.map(a -> b)는 스트림의 각 요소(a)를 꺼내 b를 수행한 결과로 매핑하겠다는 의미이고,
.collect(Collectors.tolist())는 스트림 데이터를 리스트 자료형으로 다시 반환한다는 의미이다.
스트림의 특징
- 원본 데이터를 읽기만 하고 변경하지 않는다.
- 정렬된 결과를 컬렉션이나 배열에 담아 반환할 수 있다.
- 내부 반복문으로, 반복문이 코드상에 노출되지 않는다.