Spring(기초)-2주차

Jonguk Kim·2021년 11월 15일
0

Spring

목록 보기
3/16

1. RDBMS(RDB)

RDBMS

  • 관계형 데이터베이스 (정보 저장소)
  • 컴퓨터에 정보를 저장하고 관리하는 기술
  • 매우 고도화된 엑셀
  • SQL: 데이터 읽고, 저장, 변경, 삭제하는 구체적인 문법

RDBMS의 종류

  • H2
    • In-memory DB, 인메모리 DB란 서버가 작동하는 동안에만 내용을 저장하고, 서버가 작동을 멈추면 데이터가 모두 삭제되는 데이터베이스
    • 연습용
  • MySQL
    • 스프링과 궁합이 좋음, 많은 회사에서 사용
    • 서비스 배포용
  • Oracle
  • PostgreSQL

H2 웹콘솔 띄워보기

  1. src > main > resources > application.properties > 설정 복사
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
  1. Run
  2. http://localhost:8080/h2-console 접속
  3. Connect 버튼 클릭
  4. 오류 발생시, JDBC URL에 아래를 붙여넣기
jdbc:h2:mem:testdb
  1. 테이블 생성 / 데이터 삽입 / 데이터 조회

2. JPA

JPA란?

  • SQL을 쓰지 않고 데이터를 생성, 조회, 수정, 삭제할 수 있도록 해주는 번역기 (자바로 DB를 사용하도록 도와주는 녀석)
  • 자바로 코드 작성하면 SQL 번역뿐만 아니라 기본적인 기능 거의 있음
  • 테이블: Domain, SQL: Repository

JPA가 없다면?

  • 자바 짜다가 갑자기 SQL 짜고, 그걸 잘 맞추어 넣어야함 (복잡)

JPA가 있다면?

  • 설정은 아래 한 줄이면 끝
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
  • 명령도 그냥 자바로 만들면 됨

JPA 시작하기

  1. src > main > java > com.주소명.프로젝트명에 domain 이라는 패키지 생성
  2. 클래스(Course.java), 인터페이스(CourseRepository.java) 파일 생성
  • 클래스(Course.java)
    • Id는 getter를 따로 쓰지 않음
    • Setter가 없는 이유는 repository 에서 자동으로 설정해주기 때문임
@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;
    }
}
/* 같은 개념
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)
);
*/
  • 인터페이스(CourseRepository.java)
    • extends 뒤에 있는 기능을 가져와서 쓴다는 의미
    • class Course의 id 자료형이 Long이다
    • 인터페이스: JPA는 Repository를 통해서만 사용할 수 있음 (클래스에서 멤버가 빠진, 메소드 모음집)
public interface CourseRepository extends JpaRepository<Course, Long> {
}

JPA 사용해보기

  • SQL이 보이도록 application.properties를 세팅해야한다 (resources폴더 안에 있음)
spring.jpa.show-sql=true
  • application의 메인 메소드에 아래의 코드를 붙여넣는다
// Week02Application.java 의 main 함수 아래에 붙여주세요.
@Bean
public CommandLineRunner demo(CourseRepository repository) {
    return (args) -> {

    };
}
@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());
            }
        };
    }

생성일자, 수정일자

  • extends: 클래스의 상속개념 (이미 만들어둔 것 가져다가 쓰자)
  • DB 기본 중의 기본은 "생성일자"와 "수정일자"를 필드로 가지는 것
  • domain 에서 Timestaped 클래스를 생성
package com.sparta.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;
}
  • LocalDateTime: 시간을 나타내는 자바의 자료형 중 하나
  • 어노테이션 (@~~): 스프링한테 어떤 역할인지 알려주는 것
  • Auditing: 수정해서 자료형에 자동으로 반영을 해주는 것
  • abstract: 직접 구현 불가능, 상속으로만 사용해라 -> Course에서 상속을 해준다 (Course extends Timestamped)
class Course extends Timestamped {
  • 마지막에 Application에 @EnableJpaAuditing을 붙여줘야함 (그래야 작동됨)
@EnableJpaAuditing
@SpringBootApplication
public class Week02Application {

CRUD

→ 생성 (Create)
→ 조회 (Read)
→ 변경 (Update)
→ 삭제 (Delete)

  • 데이터 저장하기 (Create) & 조회하기 (Read)
    • Repository의 save와 findAll 등을 이용
// 데이터 저장하기
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("해당 아이디가 존재하지 않습니다.")
);
  • 스프링의 구조
    • Controller : 가장 바깥 부분, 요청/응답을 처리함
    • Service : 중간 부분, 실제 중요한 작동이 많이 일어나는 부분
    • Repo : 가장 안쪽 부분, DB와 맞닿아 있음 (Repository, Entity)

Service 만들기

  1. Course 클래스에 update 메소드 추가
public void update(Course course) {
    this.title = course.title;
    this.tutor = course.tutor;
}
  1. src > main > java > com.주소명.프로젝트명 > service 패키지 생성
  2. 클래스(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();
    }
}
  1. update 실행해보기
@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());
        }
    };
}
  1. 데이터 삭제하기 (Delete)
@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();
    };
}

3. Lombok / DTO

Lombok

  • 자바 프로젝트를 진행하는데 거의 필수적으로 필요한 메소드/생성자 등을 자동생성
  • 코드 절약할 수 있도록 도와주는 라이브러리
  • 환경설정
    • command + ,
    • 검색: Annotation Processors
    • Enable 체크 후 OK
    • Shift 두 번 누르고 plugins 입력 후 엔터
    • lombok 입력 후 아이콘 우측 Install
  • Course.java
    • Course 클래스 Getter, NoArgsConstructor 적용
  • CourseService.java
    • CourseService 클래스 RequiredArgsConstructor 적용
profile
개발일지

0개의 댓글