1. RDBMS
컴퓨터에 정보를 저장하고 관리하는 기술
H2: 인 메모리 데이터베이스. 서버가 멈추면 데이터가 모두 삭제됨. 서버가 작동하는 동안에만 데이터가 저장됨.
MySQL: 서비스를 배포할 때 사용할 데이터베이스
스프링을 작동시킨 뒤에 웹 주소창에 localhost:8080/h2-console 을 입력하면 아래와 같은 창이 뜬다.
여기서 Connect 버튼을 눌러주고, 조금 기다리면 웹콘솔이 정상적으로 뜬다.
*JDBC URL은 jdbc:h2:mem:testdb 로 설정해주어야 Connect가 된다.
2. SQL 연습
-Table 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)
);
CREATE TABLE IF NOT EXISTS students (
id bigint(5) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
age varchar(255) NOT NULL,
PRIMARY KEY (id)
);
-데이터 삽입하기
INSERT INTO courses (title, tutor) VALUES
('웹개발의 봄, Spring', '남병관'), ('웹개발 종합반', '이범규');
INSERT INTO students (name, age) VALUES
('Sakuma Ritsu', '18'), ('Sena Izumi', '18');
-데이터 조회하기
SELECT * FROM courses;
3. JPA
SQL을 쓰지 않고 데이터를 생성, 조회, 수정, 삭제 할 수 있도록 해주는 번역기
domain 패키지 생성-> Courses.java 생성-> CourseRepository.java를 interface로 생성
*Courses.java
@NoArgsConstructor // 기본생성자를 대신 생성해줍니다.
@Entity // 테이블임을 나타냅니다.
public class Course {
@Id // ID 값, Primary Key로 사용하겠다는 뜻입니다.
@GeneratedValue(strategy = GenerationType.AUTO) // 자동 증가 명령입니다.
private Long id;
@Column(nullable = false) // 컬럼 값이고 반드시 값이 존재해야 함을 나타냅니다.
private String title;
@Column(nullable = false)
private String tutor;
public String getTitle() {
return this.title;
}
public String getTutor() {
return this.tutor;
}
public Course(String title, String tutor) {
this.title = title;
this.tutor = tutor;
}
}
4. 생성일자, 수정일자
domian 패키지에 Timestampled.java 생성
package com.day0922.week02.domain;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@MappedSuperclass // 상속했을 때, 컬럼으로 인식하게 합니다.
@EntityListeners(AuditingEntityListener.class) // 생성/수정 시간을 자동으로 반영하도록 설정
public abstract class Timestamped {
@CreatedDate // 생성일자임을 나타냅니다.
private LocalDateTime createdAt;
@LastModifiedDate // 마지막 수정일자임을 나타냅니다.
private LocalDateTime modifiedAt;
}
abstract는 상속으로만 쓴다고 알려주는 것
Course.java에 public class 옆에 Course extends Timestamped를 추가
Week02Application.java에 @EnableJpaAuditing 추가
h2-console에서 select * from course 를 입력하면 생성일자와 수정일자를 확인할 수 있다.
5. JPA 심화
*Week02Application.java
package com.day0922.week02;
import com.day0922.week02.domain.Course;
import com.day0922.week02.domain.CourseRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import java.util.List;
@EnableJpaAuditing
@SpringBootApplication
public class Week02Application {
public static void main(String[] args) {
SpringApplication.run(Week02Application.class, args);
}
// 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("해당 아이디가 존재하지 않습니다.")
);
}
;
}
}
Course.java에서 getId 추가
6. Service 만들기
course 클래스에 update 메소드 추가
src > main > java > com.sparta.week02 > service 패키지 생성
* Courseservice.java
@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();
}
}
@Transactional 때문에 Course 클래스 안에 update 메소드를 만들고 (전달받는 내가 변경할 정보를 가져오는 녀석) 내 정보를 바꿔주면 자동으로 데이터베이스에 적용된다.
7. 업데이트 실행하기
*Week02Application.java
package com.day0922.week02;
import com.day0922.week02.domain.Course;
import com.day0922.week02.domain.CourseRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import java.util.List;
@EnableJpaAuditing
@SpringBootApplication
public class Week02Application {
public static void main(String[] args) {
SpringApplication.run(Week02Application.class, args);
}
@Bean
public CommandLineRunner demo(CourseRepository courseRepository, CourseService courseService) {
return (args) -> {
courseRepository.save(new Course("프론트엔드의 꽃, 리액트", "임민영"));
System.out.println("데이터 인쇄");
List<Course> courseList = courseRepository.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 new_course = new Course("웹개발의 봄, Spring", "임민영");
courseService.update(1L, new_course);
courseList = courseRepository.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());
}
};
}
}
CourseService의 업데이트 기능을 활용하면 기존의 데이터가 아니라 새로운 데이터를 사용할 수 있다.
8. Delete 실행하기
courseRepository.deleteAll(); 을 마지막에 추가해주면 된다.
9. Lombok, DTO
Lombok: 코드를 절약하기 위한 녀석
Ctrl+Alt+S 를 눌러서 Annotation Process를 검색하고 Enable Annotation Processing 체크박스에 체크를 한 후, Ok를 눌러준다.
shift를 두 번 누른 뒤, Plugins를 검색, Lombok을 설치한다.
그리고 그 후에 Course 클래스에서 Getter를 전부 삭제하면, 오류가 나는데 Course 클래스의 상단에 @Getter 를 추가해주면 Lombok이 자동으로 Getter를 생성해줘서 오류가 사라지게 된다.
DTO: read, update를 할 때 테이블을 막 건드리게 되는 경우에 다른 사람이 변경을 하는 경우가 생긴다면 시스템에 오류가 생길 수도 있는데, 그것을 완충해주는 것이 DTO
domain 패키지에 코스 데이터를 물고 다니는 녀석인 CourseRequestDto.java를 생성한다.
package com.day0922.week02.domain;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
@Setter
@Getter
@RequiredArgsConstructor
public class CourseRequestDto(String title, String tutor) {
private String title;
private String tutor;
}
*CourseService.java
package com.day0922.week02.service;
import com.day0922.week02.domain.Course;
import com.day0922.week02.domain.CourseRepository;
import com.day0922.week02.domain.CourseRequestDto;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@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, CourseRequestDto requestDto) {
Course course1 = courseRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당 아이디가 존재하지 않습니다.")
);
course1.update(requestDto);
return course1.getId();
}
}
*Course.java
package com.day0922.week02.domain;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter
@NoArgsConstructor // 기본생성자를 대신 생성해줍니다.
@Entity // 테이블임을 나타냅니다.
public class Course extends Timestamped {
@Id // ID 값, Primary Key로 사용하겠다는 뜻입니다.
@GeneratedValue(strategy = GenerationType.AUTO) // 자동 증가 명령입니다.
private Long id;
@Column(nullable = false) // 컬럼 값이고 반드시 값이 존재해야 함을 나타냅니다.
private String title;
@Column(nullable = false)
private String tutor;
public Course(String title, String tutor) {
this.title = title;
this.tutor = tutor;
}
public void update(CourseRequestDto requestDto) {
this.title = requestDto.getTitle();
this.tutor = requestDto.getTutor();
}
}
10. API-GET(조회)
controller라는 새로운 패키지 생성->CourseController.java 생성
*CourseController.java
package com.day0922.week02.controller;
import com.day0922.week02.domain.Course;
import com.day0922.week02.domain.CourseRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequiredArgsConstructor
@RestController
public class CourseController {
private final CourseRepository courseRepository;
@GetMapping("/api/courses")
public List<Course> getCourses() {
return courseRepository.findAll();
}
}
*Week02Application.java
package com.day0922.week02;
import com.day0922.week02.domain.Course;
import com.day0922.week02.domain.CourseRepository;
import com.day0922.week02.domain.CourseRequestDto;
import com.day0922.week02.service.CourseService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import java.util.List;
@EnableJpaAuditing
@SpringBootApplication
public class Week02Application {
public static void main(String[] args) {
SpringApplication.run(Week02Application.class, args);
}
@Bean
public CommandLineRunner demo(CourseRepository courseRepository, CourseService courseService) {
return (args) -> {
courseRepository.save(new Course("프론트엔드의 꽃, 리액트", "임민영"));
System.out.println("데이터 인쇄");
List<Course> courseList = courseRepository.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 new_course = new Course("웹개발의 봄, Spring", "임민영");
CourseRequestDto requestDto=new CourseRequestDto();
courseService.update(1L, requestDto);
courseList = courseRepository.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());
}
//courseRepository.deleteAll();
};
}
}
*Course.java
package com.day0922.week02.domain;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter
@NoArgsConstructor // 기본생성자를 대신 생성해줍니다.
@Entity // 테이블임을 나타냅니다.
public class Course extends Timestamped {
@Id // ID 값, Primary Key로 사용하겠다는 뜻입니다.
@GeneratedValue(strategy = GenerationType.AUTO) // 자동 증가 명령입니다.
private Long id;
@Column(nullable = false) // 컬럼 값이고 반드시 값이 존재해야 함을 나타냅니다.
private String title;
@Column(nullable = false)
private String tutor;
public Course(String title, String tutor) {
this.title = title;
this.tutor = tutor;
}
public void update(CourseRequestDto requestDto) {
this.title = requestDto.getTitle();
this.tutor = requestDto.getTutor();
}
}
컴파일 후에
http://localhost:8080/api/courses
에 접속하면 아래와 같이 나온다.
Put 할 때 CourseController.java에 추가
@PutMapping("/api/courses/{id}")
public Long updateCourse(@PathVariable Long id, @RequestBody CourseRequestDto requestDto) {
return courseService.update(id, requestDto);
}
'스프링' 카테고리의 다른 글
Web server failed to start. Port 8080 was already in use. (0) | 2022.05.16 |
---|---|
5주차-완성: 익명 타임라인 페이지 (0) | 2021.08.03 |
4주차 (0) | 2021.07.31 |
스프링 3주차 (0) | 2021.07.20 |
Spring 1주차-자바 기초문법 (0) | 2021.07.06 |
댓글