오늘부터 주특기 입문, 숙련, 심화 총 3주간의 주특기 일정이 시작된다.
💡 "해봤다"는 경험을 손에 남기자, 모든 지식을 완벽히 머리에 남길 필요가 없다
(X) 상속, 추상화, 인터페이스에 대해 달달 암기하고, 세세한 부분까지 신경쓴다.
(O) 꼭 필요한 클래스, 메소드의 핵심만 기억한다. 뭘 모르는지만 기억해둔다.(X) 스프링/자바를 다루다가 아주 조금이라도 모르는게 나오면 복잡한 개념을 파고든다.
(O) 만드는 재미, 오류를 해결하는 재미에 집중하고, 나중에 공백을 채워나간다.
🚨 실력을 쌓는 길, 스스로 해결해보기
1. 오류가 나면 당황하지 말고, 에러 메시지를 차분하게 읽기!
2. 잘 모르겠다면, 에러 메시지 긁어다 구글링해보는 습관 기르기
- 환경설정에서 Auto import
파일을 새로 가져오거나 할 때 에디터가 자동으로 잡아주는 그런 역할
- 첫번째 에러를 만났다
'Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.'
에러해결
- RestController란?
JSON 형식으로 응답하는 자동 응답기
스프링이 response를 JSON 형식으로 변환해서 브라우저한테 돌려준다.
- 그레이들(Gradle)이란?
다른 사람의 코드를 다운받고 적용하는 걸 굉장히 간편하게 할 수 있다. 그리고 그걸 도와주는 녀석이 'Gradle'이다.
'Gradle'은 이런 역할 말고도 스프링 프로젝트를 배포할 수 있게 빌드한다고하는데, 그걸 도와주기도 한다.
- JPA(Spring Data JPA) - 자바 명령어를 SQL로 잘 번역해주는 녀석 ( 자바 언어를 SQL로 )
- Repository - 데이터를 접근할 때 사용하는 하나의 도구. JPA를 작동시키는 매개체
- RDBMS (관계형 정보 시스템, 관계형 데이터베이스)
- 컴퓨터에 정보를 저장하고 관리하는 기술
- 성능/관리 면에서 매우 고도화된 엑셀 이라고 생각하자- H2
- RDBMS의 한 종류, 서버가 작동할 때만 돌아가는 데이터베이스
- In-memory DB의 대표 주자
- In-memory DB란 서버가 작동하는 동안에만 내용을 저장하고, 서버가 작동을 멈추면 데이터가 모두 삭제되는 데이터베이스
- 다시 만난 에러 ㅎㅎ 당황하지않고 5분만에 해결
H2에서 테이블 생성하는데 'Syntax error in SQL statement....@#%#' 에러 메세지가 나왔다. 앞줄을 복사해서 구글링을 시도했다. 역시 나와 같은 사람이 친절하게 기록해두었다. 천천히 읽으면서 따라해보니 쉽게 해결했다. 참조했던 사이트
- 도메인[엔티티] : 테이블이랑 1:1로 대응되는 녀석
- Repository : SQL의 역할을 한다. Repository에 쓰여있는 코드가 JPA코드를 사용하는 것과 똑같다
- Setter를 설정을 안하는 이유 : Repository에서 자동으로 그런걸 다해주기때문에
@MappedSuperclass // 다른 곳에서 해당 클래스를 상속했을 때, 컬럼으로 인식하게 해라.
@EntityListeners(AuditingEntityListener.class) // 생성/수정 시간을 자동으로 반영하도록 설정
public abstract class Timestamped { // abstract : 직접 구현(new생성)은 안되고, 상속으로만 사용 가능하게
@CreatedDate // 생성일자임을 나타냅니다.
private LocalDateTime createdAt;
@LastModifiedDate // 마지막 수정일자임을 나타냅니다.
private LocalDateTime modifiedAt;
}
@EnableJpaAuditing 를 추가해줘야만 완벽하게 스프링을 통해서 반영이 된다.
.orElseThrow()에서 ()안에 어떻게 하면 되는지 메소드를 직접 작성해줘야한다.
Course myCourse = repository.findById(2L).orElseThrow(
() -> new NullPointerException("아이디가 존재하지 않습니다.")
);
- DTO
데이터를 전달하고 주고 받을 때는, 기존에 있는 클래스 사용하지 말고, 새로 클래스 만들어서 하자.
Course 클래스를 매개변수로 막 사용해도 되느냐? 아니다. 직접 저장할 때나, 찾아서 클라에게 넘겨줄 때나 이럴때나 활용해야한다. 변경하는 용도로 사용되서는 안 좋다.이처럼 쉽게 건드리게 되면 코드 작성을 하다가, 내가 아닌 다른 사람이 마음대로 실수로 변경을 하게 되면, DB가 변경될 가능성이 커지기 때문에 시스템 에러가 생길 확률이 커진다.
따라서 DB에 연결된 클래스는 그대로 두고, 우리가 정보를 물고 다니는 녀석을 따로 만들어 보자해서 탄생한게 DTO
- CRUD에 따라서 API를 나눈다. 거기에 REST라는 규칙이 있다. 여기서의 REST는 RestController랑은 다르다. 주소를 작성하는 방식에 대한 REST이다.
- @RequestBody : Controller에서 요청을 받는 녀석이다 라고 표시해주기 위한 어노테이션이다. 이게 없으면 'CourseRequestDto requestDto' 안에 쏙 안들어간다. 스프링은 요청을 주고받는 방식을 강제한다.
- 스프링은 request할때 Headers의 Content-Type을 application/json으로 강제하고 있다.
List<Memo> findAllByOrderByModifiedAtDesc();
// 메소드 명을 JPA 규칙에 맞게 만들면 JPA가 이해하고 쿼리를 변형시켜 실행한다.
data: JSON.stringify(data)
// String 형태로만 주고 받을 수 있기때문에 String으로 변환
- textarea는 .val( )로 가져오고,
- div 안에 읽기모드처럼 텍스트로 박혀있는 녀석을 가져올 때는 .text( )
3주차 숙제
타임라인 서비스가 불러오는 메모 목록의 시간을,
조회 시간으로부터 24시간 이내로 바꿔보세요.
이전) 수정시간 최신순 정렬
List<Memo> findAll ByOrderBy ModifiedAt Desc();
이후)
findAllByModifiedAtBetweenOrderByModifiedAtDesc(startDatetime, endDatetime)
findAll: 모두 찾아라
ByModifiedAtBetween: 수정된 시간들 사이(start,end) 에서
OrderByModifiedAtDesc: 수정된 시간을 기준으로 내림차순
List<Memo> findAllByModifiedAtBetweenOrderByModifiedAtDesc(LocalDateTime start, LocalDateTime end);