목록분류 전체보기 (134)
도슐랭스타

CORS란?브라우저에서 보안적인 이유로 cross-origin HTTP 요청들을 제한함! 그래서 서버의 동의가 필요함.→ 서버에게 허락을 구하고 승인/거절하는 과정을 HTTP-header룰 이용해서 할 수 있음.→ 이것을 Cross-Origin Resource Sharing라고 함.cross-origin은1. 프로토콜(http or https)2. 도메인3. 포트번호중 하나라도 다른 경우임.cors설정↓WebConfig.Javapackage me.dodo.readingnotes.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org..
요구사항 정리사용자는 책 제목, 작가, 날짜를 기준으로 검색하고 싶어함1개만 검색하거나, 여러 개를 조합해서도 검색 가능 ReadingRecordRepository.javaList findByTitleContainingAndAuthorContainingAndDate( String title, String author, LocalDate date);JPA Query 메서드를 사용해서 findBy - JPA에서 무언가를 "찾겠다"는 뜻TitleContaining - title 필드에 이 문자열이 포함된 데이터를 찾음. LIKE %keyword%와 같음. AndAuthorContaining - author에도 이 문자열이 포함돼야 함. AndDate - 날짜는 정확히 일치해야 함. = yyyy-mm-..
useMemo()복잡한 계산 결과를 기억(memoization) 해서, 불필요한 계산을 피하고 성능을 향상시키는 Hook Memoization (메모이제이션)- 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술 -> 성능 최적화 - 메모이제이션 된 결과값이 Memoized value계산량이 많은 작업(compute함수)의 경우 컴포넌트가 랜더링될 때마다 수행하면 UI 지연 발생-> useMemo() 훅이 필요렌더링이 일어나는 동안 실행되서는 안되는 작업은 useMemo()에 사용하면 안됨 - useEffect()에서 실행돼야 할 이펙트 작업임. 1. 의존성 배열을 넣지 않으면? const..

const [count, setCount] = useState(0);function handleClick() { setCount(count + 1); setCount(count + 1);}두 번 더했으니까 count는 2가 되겠지?" 하고 생각할 수 있지만 실제로는 count가 1만 됨.count는 현재 렌더링 시점의 값(0) 이고, setCount(count + 1)은 두 번 다 setCount(1)이 되기 때문.-> setCount(1)처럼 상태를 바꾸면, 바로 즉시 count 값이 1로 바뀌는 게 아님 set 함수는 비동기적으로 작동하며 현재 렌더링된 시점의 값이 반영됨 해결 방법함수형 업데이트를 쓰기const [count, setCount] = useState(0);function handl..

Java로 만든 경량형 관계형 데이터베이스(RDBMS)메모리 또는 파일 기반으로 동작할 수 있음.설치 없이 바로 사용 가능함.개발/테스트 단계에서 굉장히 많이 쓰이는 DB임.H2의 장점이 뭐지?가벼움 - 설치 X, JAR로 바로 사용 가능 (내장형)빠름 - 메모리에서 동작하므로 속도 빠름개발에 최적 - 실행할 때마다 DB가 초기화되기 때문에 테스트하고 바로 버릴 수 있음. (휘발성) 웹 콘솔 제공함 - /h2-console로 웹에서 SQL 직접 확인 가능자동 테이블 생성 가능 - JPA 설정만 해두면 @Entity만으로 테이블 생성됨JPA 테스트에 적합함 - Repository 테스트, Service 테스트를 할 때 가짜 DB 대신 실제 JPA 작동 방식 그대로 확인 가능.단점도 있긴 함.휘발성 메모리..

DTO = Data Transfer Object 데이터를 전송하기 위한 객체 요청이나 응답에 사용할 데이터만 따로 담아두는 전용 박스아니 처음에 DTO가 전혀 이해가 안 가는 겁니다.이거 왜 쓰는데?! 뭐가 다른데?! 으악코드 먼저 보겠습니다.ReadingRecordRequest.javapackage me.dodo.readingnotes.dto;import java.time.LocalDate;public class ReadingRecordRequest { private String title; private String author; private LocalDate date; private String content; // 기본 생성자 // 없으면 JPA와 동일하게 Jac..

사용자가 요청을 처리함[사용자 클릭] → [Controller] → [Service] → [Repository] → [DB 저장]ReadingRecordController.javapackage me.dodo.readingnotes.controller;import me.dodo.readingnotes.domain.ReadingRecord;import me.dodo.readingnotes.service.ReadingRecordService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController@Req..
Controller(요청 받는 곳)와 Repository(DB와 연결되는 곳) 사이에서 실제 로직을 처리하는 역할.ex. "책을 저장하되, 제목이 없으면 저장하지 마!" 같은 유효성 검사도 여기서 처리함.Service를 왜 만드냐?비즈니스 로직(Service)와 DB 로직(Repository)를 분리할 수 있음.비즈니스 로직(Service) - 유효성 검사, 수량 확인 등DB 로직(Repository) - DB에 저장구조장점 단점Controller → Repository빠르게 구현, 간단로직이 섞이면 복잡해짐Controller → Service → Repository유지보수 좋고 재사용 가능코드 구조가 조금 더 복잡해짐ReadingRecordService.javapackage me.dodo.reading..
Repository는 JPA가 제공하는 '자동 DAO(데이터 접근 객체)'DAO(Data Access Object) - 실제 DB에 접근하여 CRUD하는 객체ReadingRecordRepository.javapackage me.dodo.readingnotes.repository;import me.dodo.readingnotes.domain.ReadingRecord;import org.springframework.data.jpa.repository.JpaRepository;public interface ReadingRecordRepository extends JpaRepository { // 필요하면 여기에 커스텀 쿼리도 작성}public interface ReadingRecordRepository ..
DB와 매핑될 클래스 생성.POST로 받을 책 내용들 저장하는 구조.파일 위치src/main/java/your_package_name/domain/ReadingRecord.javadomain은 모델 객체를 넣는 일반적인 디렉터리명임.ReadingRecord.javapackage me.dodo.readingnotes.domain;import jakarta.persistence.*;import java.time.LocalDate;@Entity //이 클래스가 JPA 엔티티임을 선언. DB 테이블과 매핑됨@Table(name = "reading_record") //DB에서 이 엔티티가 매핑될 테이블 이름을 지정함public class ReadingRecord { @Id //이 필드(id)가 **기본 키(..