Spring 기초 2주차

Doyoon Lee·2021년 8월 11일
0

Spring

목록 보기
2/7

RDBMS

  • RDBMS(Relational DataBase Management System)은 컴퓨터에 정보를 저장하고 관리하는 기술이다.
  • 성능/관리 면에서 매우 고도화된 엑셀이라고 생각해도 좋다.
  • 종류
    • MySQL
    • PostgreSQL
    • Oracle Database
      cf) H2: In-memory DB(서버가 작동하는 동안에만 내용을 저장)
  • h2 web-console 설정
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
  • 'src-main-resources-application.properties' 안에 위 내용 추가
  • localhost:8080/h2-console 창으로 들어가면 확인 가능

SQL 연습하기

테이블 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;

JPA 시작하기

  • JPA: SQL을 쓰지 않고 데이터를 생성, 조회, 수정, 삭제할 수 있도록 해주는 번역기
  • JPA가 없다면 자바를 짜다가 갑자기 SQL을 짜야하는 상황이 있을 수 있다.
  • JPA는 Repository(Interface)를 통해서만 사용할 수 있다.
  • Interface는 클래스에서 멤버가 빠진, 메소드 모음집이라고 볼 수 있다.

JPA 사용해보기

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를 빨리 써보기 위한 임시로 만든 코드

생성일자, 수정일자

  • 상속(extends)의 개념: 클래스의 상속"
  • DB 기본 중의 기본은, "생성일자"와 "수정일자"를 필드로 가지는 것이다.

Timestamped로 상속 연습하기

@MappedSuperclass // 상속했을 때, 컬럼으로 인식하게 합니다.
@EntityListeners(AuditingEntityListener.class) // 생성/수정 시간을 자동으로 반영하도록 설정
public class Timestamped {
    @CreatedDate // 생성일자임을 나타냅니다.
    private LocalDateTime createdAt;
    @LastModifiedDate // 마지막 수정일자임을 나타냅니다.
    private LocalDateTime modifiedAt;
}
  • Course 클래스에 extends Timestamped를 추가한다.
  • 또한 Week02Application 클래스에 @EnableJpaAuditing을 추가한다. 이 어노테이션을 추가함으로 인해 생성/수정일자가 자동으로 업데이트될 것이다.

JPA 심화

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 때문에 해당 정보가 자동으로 반영이 된다.

Lombok

  • 자바 프로젝트를 진행하는데 거의 필수적으로 필요한 메소드/생성자 등을 자동생성해줌으로써 코드를 절약할 수 있도록 도와주는 라이브러리이다.
  • 환경설정에서 compiler-Annotation Processors 탭에 들어가서 Enable annotation processing을 활성화해준다. 이는 @를 더 잘 작성할 수 있게끔 인텔리제이가 지원해달라는 뜻이다.
  • 추가적으로 Plugins에서 Lombok을 설치해준다.
  • 작성하는 class 위에 @Getter/@RequiredArgsConstructor와 같이 붙여주면 자동적으로 해당 메소드가 생성된다.

DTO

  • data transfer object
  • 데이터를 전달하고 주고 받을 때는 새로 클래스를 만들어서 하자는 뜻(기존의 클래스 사용 x)이다.
  • 클래스 정보를 실수로 변경하여 DB가 바뀌는 경우를 대비하기 위해 존재한다.

API

  • 클라이언트와 서버 간의 약속
  • 클라이언트가 정한대로 서버에게 요청(Request)를 보내면, 서버가 요구사항을 처리하여 응답(Response)를 반환한다.
  • API를 설정하는 것은 기본적으로 네 가지 기준이 있다. CRUD(생성(POST)/조회(GET)/수정(PUT)/삭제(DELETE))에 따라서 API를 나누곤 한다.
  • REST라는 규칙이 있다. REST란 주소를 작성하는 방식으로, 주소에는 명사 + 요청 방식에 동사를 사용함으로써 의도를 명확히 드러냄을
  • REST 주의사항
    - 주소에 들어가는 명사들은 복수형을 사용한다.
    - 주소에 동사는 가급적 사용하지 않는다.
    cf) API를 만들고 난 후, ARC(Advanced REST Client)로 테스트 및 기능 확인 가능

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에 넣어준다.

0개의 댓글