[TIL] Spring Boot 3일차
Today I learned...
면접에서 탈락한 이후 Spring과 Java에 대해 다시 한 번 흥미를 느끼면서 관심이 가기 시작했다. 우선은 스스로 정한 테크 스택은 다음과 같다.
- Spring Boot (Java, Kotlin)
- Node.js, Nest.js (TypeScript)
- React
- Problem Solving (Python, Java)
- Native CLI Program (C++)
휴학을 시작한 지 5개월 만에 정한 거 같아 조금 늦은 감이 없잖아 있긴 하지만 어떠한가, 아직 졸업할려면 많은 기한이 남았기 때문에 심기일전 해볼려고 한다. 우선 최근에 배우고 있는 것은 Spring Boot와 AWS 로 혼자 구현하는 웹서비스 이다. 이동욱 님께서 저술하신 책인데 상당히 편하게 쭉쭉 읽을 수 있는 게 자바 초보(?)에 Spring 문외한인 나도 읽으면서 동시에 서비스를 만들 수 있어서 좋은 거 같다. 다만, 나는 어느 정도 기초 지식을 나무위키라던지 블로그를 읽으면서 알고 있었기에 그래도 읽으면서 모르는 부분이 있을 지언정 이해가 안되는 것은 아니였다고 생각한다. 즉, 아예 모르는 사람은 조금 보충 설명이라던지, 다른 책으로 스타트를 끊는 것이 조금 더 낫지 않을까 하고 생각한다.
챕터 3 - JPA와 API를 통한 데이터베이스 입출력
과거에는 SQL Mapper를 통하여 Spring에서 데이터를 DB에 넣어주는 작업을 했다고 한다. (난 애초에 ORM밖에 안 써봐서 잘 모르지만..) SQL을 다루는 시간과 유지보수성이 너무나 안 좋아 JPA (Java Persistence API)란 ORM (Object Relation Mapping)을 사용하여 데이터와 객체를 영속화 시켜주는 기술이 등장했다고 서술되어 있다.
즉, 개발자는 SQL 쿼리를 만들 필요가 없다. 그냥 JPA를 통해 적절한 메소드를 호출하기만 하면 된다.
@Getter
@NoArgsConstructor // 기본 생성자 자동 추가, Posts()로도 객체 생성 가능
@Entity // 테이블과 링크될 클래스임을 표기 (기본값으로 카멜케이스 이름을 언더스코어 네이밍으로 이름을 지칭)
public class Posts extends BaseTimeEntity {
@Id // PK 필드
@GeneratedValue(strategy = GenerationType.IDENTITY) // PK 생성 규칙, IDENTITY로 인하여 auto_increment가 됨
private Long id;
@Column(length = 512, nullable = false) // 기본적으로 모든 필드는 칼럼이 되지만, 기본값 이외의 옵션을 줘야할 때
private String title;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
private String author;
@Builder // 해당 클래스를 빌더 클래스로 만들 수 있음. 생성자 상단에 선언 시 생성자에 포함된 필드만 가능
public Posts(String title, String content, String author) {
this.title = title;
this.content = content;
this.author = author;
}
/**
* 데이터를 업데이트하는 기능을 포함한다
* JPA의 엔티티 매니저가 활성화된 상태 하에 트랜잭션 안에서 DB에서 데이터를 가져오면 이는 영속성 컨텍스트가 유지된 상태
* 즉, 해당 데이터의 값을 변경하면, 트랜잭션이 끝나는 시점에서 해당 테이블에 변경분을 자동으로 반영 (업데이트)
* Update 쿼리를 날리지 않아도 된다. 이를 Dirty Checking 이라고 한다.
* @param title
* @param content
*/
public void update(String title, String content) {
this.title = title;
this.content = content;
}
}
/***
* 자바빈 규약에선 getter/setter를 생성하지만, Entity Class에선 Setter 메소드를 절대 생성하지 않는다.
* 변경이 필요하면 명확히 목적과 의도를 나타낼 수 있는 메소드만 추가해야한다.
*/
위에 Entity 클래스는 실제로 저장되는 데이터를 객체로 표현해준다. JPA는 이를 분석하여 데이터베이스에 데이터를 넣고, 읽고, 쓰고, 지우면서 그 데이터를 해당 Entity 클래스와 영속화 시켜준다. 이를 영속성 컨텍스트라고 한다.
참고로 상속을 통해서도 저장할 데이터를 확장할 수 있고, 이를 통해 데이터 객체의 재사용성을 높일 수 있다 (예: CreatedTime, ModifiedTime과 같은 모든 데이터에 필요한 메타적 정보들이 여러 곳에서 사용될 때)
오늘 배운 어노테이션
@Entity : Entity Class 임을 선언한다.
@NoArgsConstructor : Default 생성자를 자동으로 만들어준다.
@RequiredArgsConstructor : `final`이나 `@NotNull`이 붙은 필드들의 생성자를 자동으로 생성해주는 어노테이션. Spring에선 이 어노테이션으로 자동으로 빈을 주입할 수 있게 된다.
@Service : Component이나, 내부적으로 그것이 서비스 로직임을 알려주는 어노테이션. 기능적으로는 차이가 없다.
@Trnasactional : 연산을 고립시켜주고, 다른 연산이 해당 연산을 방해하지 않도록 보장한다. + 연산이 오류가 발생하면 그 연산을 commit하지 않는다. [자료](https://kafcamus.tistory.com/30)
@MappedSuperclass : JPA Entity클래스들이 이 클래스를 상속하는 경우 자동으로 필드들을 인식하게 함 - @EntityListeners(AuditingEntityListener.class) : 해당 클래스에 Auditing 기능을 포함시킴
@EnableJpaAuditing : 해당 Spring Application 전체가 JPA Auditing을 사용할 수 있게 함
@RequestBody : HTTP Body를 매개변수의 DTO 객체로 매핑한다.
@PathVariable : URL 내부에 {var_name}와 같은 형식에서 var_name을 가져와 그것을 매개변수에 담아준다.
What I was wondering is...
아무래도 실전에 치중된 책이다 보니 이런 이론적인 부분들에 대한 설명이 좀 부족하다고 느낀다. 그래서 직접 찾아봤다.
스프링 빈이란?
의존성 주입이란?
RequiredArgsConstructor를 통하지 않은 의존성 주입
RequestTemplate이란?
Tomorrow, I will learn...
- Ch04를 마무리 할 것이다.
- 토익 영어 공부를 할 것이다.
- 블로그 TIL 시리즈를 마찬가지로 작성할 것이다.