1. RDBMS
RDBMS(Relational DataBase Management System)은 컴퓨터에 정보를 저장하고 관리하는 기술이다. 쉽게 생각하면 성능/관리 면에서 매우 고도화된 엑셀이라고 보면 된다.
우리가 사용할 RDBMS의 종류는 H2, MySQL 두 가지이다.
H2는 서버가 작동하는 동안에만 내용을 저장하고, 서버가 작동을 멈추면 데이터가 모두 삭제되는 데이터베이스이다. 연습용으로 가장 적합하다.
MySQL 은 우리가 서비스를 배포할 때 사용할 데이터베이스이다. AWS RDS라는 서비스를 사용해 붙여볼 예정인데, 스프링과 궁합이 좋아서 많은 회사에서 사용한다.
2. JPA
JPA는, SQL을 쓰지 않고 데이터를 생성, 조회, 수정, 삭제할 수 있도록 해주는 번역기이다.
JPA는 자바로 DB를 사용할 수 있도록 도와주는 역할을 가지고 있는데, 그럼 DB 를 이용하는데 핵심이었던 "테이블"과 "SQL"과 동일한 개념의 자바 용어가 있다. "테이블" 은 Domain, "SQL" 은 Repository이다.
Week02 프로젝트에 Course라는 테이블에 title, tutor라는 칼럼을 만들어 두었는데, 이것을 자바로 표현하면,
(1) src > main > java > com.sparta.week02에 domain 패키지 생성
(2) Course.java, CourseRepository.java 파일 생성
Course.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;
}
}
CourseRepository.java
public interface CourseRepository extends JpaRepository<Course, Long> {
}
3. JPA 심화
CRUD : 생성(Creat), 조회(Read), 변경(Update), 삭제(Delete)
1. 데이터 저장하기 (Create) & 조회하기 (Read)
- Repository의 save와 findAll 등을 이용한다.
Create & Read Java 코드
// 데이터 저장하기
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("해당 아이디가 존재하지 않습니다.")
);
2. Service
update, delete를 하기 전에, 다루어야 하는 개념이 Service이다.
- 스프링의 구조는 3가지 영역으로 나눌 수 있습니다.
- Controller : 가장 바깥 부분, 요청/응답을 처리함.
- → 2주 차 후반부에 배울 녀석
- Service : 중간 부분, 실제 중요한 작동이 많이 일어나는 부분
- → 지금 배울 녀석
- Repo : 가장 안쪽 부분, DB와 맞닿아 있음.
- → 여태 배운 녀석 (Repository, Entity)
- Update는 Service 부분에 작성합니다.
Service를 만들기 위해선,
(1) Course.java 에 update 메서드 추가
public void update(Course course) {
this.title = course.title;
this.tutor = course.tutor;
}
(2) src > main > java > com.sparta.week02 > service 패키지 생성
(3) 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();
}
}
3. 데이터 변경(Update)
Week02 Application.java 에 메소드 추가
@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());
}
};
}
4. 데이터 삭제(Delete)
Week02Application.java 에 courseRepository.deleteAll(); 추가
@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());
}
courseRepository.deleteAll();
};
}
4. Lombok
Lombok 은 자바 프로젝트를 진행하는데 거의 필수적으로 필요한 메서드/생성자 등을 자동 생성해줌으로써 코드를 절약할 수 있도록 도와주는 라이브러리이다.
Lombok을 사용하기 위해선,
(1) Course.java 에 Getter, NoArgsConstructor 적용
(2) CourseService.java 에 RequiredArgsConstructor 적용
5. DTO
테이블을 막 건드려도 될까? read, update 할 때 Course 클래스를 막 써도 될까?
내가 아닌 다른 사람이 변경이라도 한다면 안되기 때문에 완충재로 활용하는 것이 DTO(Data Transfer Object)이다.
DTO를 사용하기 위해선,
(1) src > main > java > com.sparta.week02 > models에 CourseRequestDto 파일 생성
(2) CourseRequestDto.java 작성
@NoArgsConstructor
@Getter
public class CourseRequestDto {
private String title;
private String tutor;
public CourseRequestDto(String title, String tutor) {
this.title = title;
this.tutor = tutor;
}
}
(3) CourseService.java 변경
@RequiredArgsConstructor
@Service
public class CourseService {
private final CourseRepository courseRepository;
@Transactional
public Long update(Long id, CourseRequestDto requestDto) {
Course course1 = courseRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당 아이디가 존재하지 않습니다.")
);
course1.update(requestDto);
return course1.getId();
}
}
(4) Course.java 변경
@Getter
@NoArgsConstructor
@Entity
public class Course extends Timestamped {
@Id
@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();
}
}
(5) Week02 Application.java 변경
@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());
}
CourseRequestDto requestDto = new CourseRequestDto("웹개발의 봄, Spring", "임민영");
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();
};
}
}
6. API
(1) API
API 란 클라이언트 - 서버 간의 약속이다. 클라이언트가 정한 대로 서버에게 요청(Request)을 보내면, 서버가 요구사항을 처리하여 응답(Response)을 반환한다.
(2) REST
REST 란, 주소에 명사, 요청 방식에 동사를 사용함으로써 의도를 명확히 드러냄을 의미한다. 여기에 쓰이는 동사는 JPA에서 배운 CRUD를 지칭한다.
7. API - GET, POST, PUT
1. 데이터 조회 API(GET)
(1) src > main > java > com.sparta.week02 아래에 controller 패키지 생성
(2) CourseController.java 생성
@RequiredArgsConstructor
@RestController
public class CourseController {
private final CourseRepository courseRepository;
@GetMapping("/api/courses")
public List<Course> getCourses() {
return courseRepository.findAll();
}
}
(3) Week02 Application.java 실행
(4) http://localhost:8080/api/courses 접속하여 확인
2. 데이터 생성 API(POST)
(1) CourseController.java 에 PostMapping 추가
private final CourseService courseService;
// PostMapping을 통해서, 같은 주소라도 방식이 다름을 구분합니다.
@PostMapping("/api/courses")
public Course createCourse(@RequestBody CourseRequestDto requestDto) {
// requestDto 는, 생성 요청을 의미합니다.
// 강의 정보를 만들기 위해서는 강의 제목과 튜터 이름이 필요하잖아요?
// 그 정보를 가져오는 녀석입니다.
// 저장하는 것은 Dto가 아니라 Course이니, Dto의 정보를 course에 담아야 합니다.
// 잠시 뒤 새로운 생성자를 만듭니다.
Course course = new Course(requestDto);
// JPA를 이용하여 DB에 저장하고, 그 결과를 반환합니다.
return courseRepository.save(course);
}
(2) Course.java 에 생성자 추가
public Course(CourseRequestDto requestDto) {
this.title = requestDto.getTitle();
this.tutor = requestDto.getTutor();
}
ARC에서 도메인 입력 후, POST로 실행 시, 400 에러가 뜬다.
그렇기 때문에 따로 데이터를 생성하기 위해선 하단 HADERS를 클릭하고, Header name과 Parameter value를 각각 아래와 같이 입력한다.
- Header name : Content-Type
- Parameter value : application/json
그다음 BODY 탭을 클릭하고, 아래와 같이 입력한다.
그 후 Send 버튼을 클릭하면 아래와 같이 데이터가 생성된다.
생성한 후 GET을 이용해 데이터 조회를 해보면,
생성된 데이터 조회를 할 수 있다.
3. 데이터 수정 API(PUT)
(1) CourseController.java 에 PutMapping 추가
@PutMapping("/api/courses/{id}")
public Long updateCourse(@PathVariable Long id, @RequestBody CourseRequestDto requestDto) {
return courseService.update(id, requestDto);
}
ARC로 데이터를 수정할 경우,
- Method : PUT
- URL : http://localhost:8080/api/courses/1 (id 가 1인 데이터를 수정)
- Header name : Content-Type
- Parameter value : application/json
BODY 에는 수정 할 데이터를 입력한다.
Send 후 GET을 사용해 조회를 해보면,
id 가 1인 데이터가 수정된 것을 볼 수 있다.
이상 끝 ٩( ᐛ )و
'스파르타 코딩클럽 > Spring' 카테고리의 다른 글
[스파르타 코딩 클럽] Spring 4주차 개발일지 - 네이버 API 를 사용해 셀렉샵 구현 (0) | 2021.08.19 |
---|---|
[스파르타 코딩 클럽] Spring 3주차 개발일지 - Spring 을 사용해 Memo 웹페이지 구현 (0) | 2021.08.12 |