spring.h2.console.enabled=true spring.datasource.url=jdbc:h2:mem:testdb
- 'src-main-resources-application.properties' 안에 위 내용 추가
- localhost:8080/h2-console 창으로 들어가면 확인 가능
테이블 courses 생성하기
CREATE TABLE IF NOT EXISTS courses ( id bigint(5) NOT NULL AUTO_INCREMENT, title varchar(255) NOT NULL, tutor varchar(255) NOT NULL, PRIMARY KEY (id) );
courses 데이터 삽입
INSERT INTO courses (title, tutor) VALUES ('웹개발의 봄, Spring', '남병관'), ('웹개발 종합반', '이범규');
courses 데이터 조회
SELECT * FROM courses;
spring.jpa.show-sql=true
- SQL이 보이도록 application.properties 세팅
- 스프링이 JPA로 작동을 할 때 SQL을 보여달라는 뜻
- 자바 명령어를 SQL로 바꿔서 직접 실행한다는 것을 보여주기 위해 사용
// Week02Application.java 의 main 함수 아래에 붙여주세요. @Bean public CommandLineRunner demo(CourseRepository repository) { return (args) -> { Course course1 = new Course("웹개발의 봄, Spring", "남병관"); repository.save(course1); List<Course> courseList = repository.findAll(); for (int i=0; i<courseList.size(); i++) { Course c = courseList.get(i); System.out.println(c.getTitle()); System.out.println(c.getTutor()); } }; }
- 진짜 프로젝트를 만들면 이런식으로 쓰는 일은 없다.
- JPA를 빨리 써보기 위한 임시로 만든 코드
Timestamped로 상속 연습하기
@MappedSuperclass // 상속했을 때, 컬럼으로 인식하게 합니다. @EntityListeners(AuditingEntityListener.class) // 생성/수정 시간을 자동으로 반영하도록 설정 public class Timestamped { @CreatedDate // 생성일자임을 나타냅니다. private LocalDateTime createdAt; @LastModifiedDate // 마지막 수정일자임을 나타냅니다. private LocalDateTime modifiedAt; }
- Course 클래스에 extends Timestamped를 추가한다.
- 또한 Week02Application 클래스에 @EnableJpaAuditing을 추가한다. 이 어노테이션을 추가함으로 인해 생성/수정일자가 자동으로 업데이트될 것이다.
CRUD란? 정보관리의 기본 기능
- 생성(Create)
- 조회(Read)
- 변경(Update)
- 삭제(Delete)
Create & Read 해보기
// Week02Application.java 의 main 함수 아래에 붙여주세요. @Bean public CommandLineRunner demo(CourseRepository repository) { return (args) -> { // 데이터 저장하기 repository.save(new Course("프론트엔드의 꽃, 리액트", "임민영")); // 데이터 전부 조회하기 List<Course> courseList = repository.findAll(); for (int i = 0; i < courseList.size(); i++) { Course course = courseList.get(i); System.out.println(course.getId()); System.out.println(course.getTitle()); System.out.println(course.getTutor()); } // 데이터 하나 조회하기 Course course = repository.findById(1L).orElseThrow( () -> new IllegalArgumentException("해당 아이디가 존재하지 않습니다.") ); }; } }
Service의 개념
- update, delete로 넘어가기 전에 다루어야 하는 개념이 Service이다.
- 스프링의 구조는 3가지 영역으로 나눌 수 있다.
- Controller: 가장 바깥 부분, 요청/응답을 처리함.
- Service: 중간 부분, 실제 중요한 작동이 많이 일어나는 부분으로 Controller와 Repository 사이의 연결고리
- Repository: 가장 안쪽 부분, DB와 맞닿아 있음
- update는 service 부분에 작성한다.
@Service // 스프링에게 이 클래스는 서비스임을 명시 public class CourseService { // final: 서비스에게 꼭 필요한 녀석임을 명시 private final CourseRepository courseRepository; // 생성자를 통해, Service 클래스를 만들 때 꼭 Repository를 넣어주도록 // 스프링에게 알려줌 public CourseService(CourseRepository courseRepository) { this.courseRepository = courseRepository; } @Transactional // SQL 쿼리가 일어나야 함을 스프링에게 알려줌 public Long update(Long id, Course course) { Course course1 = courseRepository.findById(id).orElseThrow( () -> new IllegalArgumentException("해당 아이디가 존재하지 않습니다.") ); course1.update(course); return course1.getId(); } }
- @Service는 스프링한테 서비스임을 알리고 있다.
- update 메소드의 return 값은 Long이다. 업데이트가 끝난 요소의 ID를 돌려준다.
- 업데이트할 때 필요한 파라미터는 업데이트 시킬 요소의 ID와 업데이트할 정보를 가져올 요소가 필요.
- 그 후, repository에서 해당 id를 찾고, 그 후, Course 클래스에 적어놓은 update 메소드를 이용해 해당 요소를 update 시킨다.
- 이러한 update는 @Transactional 때문에 해당 정보가 자동으로 반영이 된다.
GET
@RequiredArgsConstructor @RestController public class CourseController { private final CourseRepository courseRepository; @GetMapping("/api/courses") public List<Course> getCourses() { return courseRepository.findAll(); } }
POST
// PostMapping을 통해서, 같은 주소라도 방식이 다름을 구분 // PostMapping을 통해서, 같은 주소라도 방식이 다름을 구분 @PostMapping("/api/courses") // @RequestBody가 있어야 요청한 정보가 RequestDto 안으로 들어간다. // requestDto 는, 생성 요청을 의미. public Course createCourse(@RequestBody CourseRequestDto requestDto) { // 저장하는 것은 Dto가 아니라 Course이니, Dto의 정보를 course에 담아야 함. Course course = new Course(requestDto); // JPA를 이용하여 DB에 저장하고, 그 결과를 반환합니다. return courseRepository.save(course); }
- POST로 데이터를 보낼때는 엄격한 규칙을 따라야한다.
- HEADERS: name - Content-Type / value - application/json
- BODY: json 형식
PUT
@PutMapping("/api/courses/{id}") public Long updateCourse(@PathVariable Long id, @RequestBody CourseRequestDto requestDto) { return courseService.update(id, requestDto); }
- @PathVariable로 인해 {id}값을 Long id에 넣어준다.