[북스터디] 스프링 프레임워크 첫걸음 02

jina·2024년 6월 29일

Spring

목록 보기
4/8

'스프링 프레임워크 첫걸음' 책을 읽고 배운 개념 중 데이터베이스와 관련된 부분을 정리했습니다 💭

📌 데이터베이스

데이터베이스는 '데이터를 보관하는 상자'를 말합니다. 그 중 데이터를 테이블 형식으로 보관하는 상자를 관계형 데이터베이스(RDB)라고 부릅니다. 테이블은 가로 행(row)와 세로 열(column)을 갖고 있으며, 한 건의 데이터가 하나의 가로 행에 입력됩니다. 이렇게 입력된 데이터에는 제약조건(Constraint)를 설정해서 관리할 수 있습니다.

✅ 제약 조건 (Constraint)

아래와 같은 제약 조건을 사용할 수 있습니다.

  • NOT NULL: 필수 입력이 필요할 때 사용
  • UNIQUE: 고유한 값을 가져야 할 때 사용
  • CHECK: 지정한 조건을 만족하지 않을 때 입력을 불허
  • PRIMARY KEY: 레코드를 식별할 수 있는 기본키 (NOT NULL + UNIQUE)
  • FOREIGN KEY: 다른 테이블과 연결되어 있음을 보여주는 외부 키
  • DEFAULT: 칼럼 초기값 설정
-- Users 테이블 데이터를 만들고 제약 조건 설정하는 예시
CREATE TABLE users (
	user_id INT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(100) NOT NULL,
    age INT CHECK (age >= 18), -- CHECK: 18 미만의 숫자 입력 불가
    create_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP --  TIMESTAMP: 타임존 포함한 현재 날짜와 시간
);

📌 엔티티 & 레포지토리

데이터베이스를 사용하려면 데이터를 담아두는 객체인 엔티티(Entity)와 조작을 담당하는 레포지토리(Repository)가 필요합니다.

✅ 엔티티 클래스

  • 엔티티 클래스는 데이터베이스 테이블에 대응하는 클래스입니다.
  • 클래스의 각 인스턴스는 데이터베이스 테이블에 속한 각각의 레코드(행)을 나타냅니다.
  • 클래스의 필드는 데이터베이스 테이블의 열(컬럼)에 대응합니다.
// 엔티티 클래스 예시
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    private Long id;

    private String email;
    private String password;
}

✅ 레포지토리 인터페이스

  • 레포지토리 클래스는 데이터베이스를 조작하는 클래스입니다.
  • 인터페이스로 정의해야 하며 JpaRepository를 구현해서 사용할 수 있습니다.
  • Spring Data JPA 프레임워크가 자동으로 해당 인터페이스의 구현체를 생성해줍니다.spring-boot-starter-data-jpa 종속성을 추가해 사용할 수 있습니다.
  • 데이터베이스 드라이버 종속성도 별도로 추가가 필요합니다. (예, MySQL: mysql-connector-java)
  • 데이터베이스를 조작하는 데 필요한 CRUD 메소드가 자동으로 만들어집니다.

아래는 PostgreSQL을 사용하는 경우 application.properties 파일에 필요한 설정 예시입니다.

# 데이터베이스 연결 정보
spring.datasource.url=jdbc:postgresql://localhost:8080/mydatabase
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.username=myusername
spring.datasource.password=mypassword

# JPA 설정
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect

# Hibernate DDL 설정 (선택사항)
spring.jpa.hibernate.ddl-auto=update

# Hibernate의 SQL 로그 출력 설정 (선택사항)
spring.jpa.show-sql=true

레포지토리 인터페이스를 설정하는 예시입니다.
@Repository 어노테이션은 클래스에 사용되며, 인터페이스는 인스턴스화 할 수 없기 때문에 붙이지 않습니다.

public interface CustomerRepository extends JpaRepository<Seller, Long> {
    Optional<Seller> findByEmail(String email);
}

✅ O/R 매퍼 (ORM 매퍼)

ORM 매퍼는 RDB와 객체 사이를 자동으로 연결하는 프레임워크를 뜻합니다.

  • 대표적인 ORM 매퍼: Hibernate, JPA
  • JPA: RDB와 객체를 연결하는 규칙을 정의한 인터페이스
  • Hibernate: JPA 규칙을 실제로 구현하고 동작시키는 라이브러리

Spring Data JPA는 JPA 규칙을 사용하게 도와주는 스프링 모듈이며, JPA를 구현하기 위해 Hibernate를 구현체로 사용합니다.

📌 MVC

✅ MVC 모델

MVC 모델은 프로그램 작성을 처리 역할에 따라 분류한 모델입니다. 비슷한 역할에 따라 코드를 구조화하기 때문에 유지보수성을 향상시키고 사용자에게 더 나은 서비스를 제공하는 데 도움이 될 수 있습니다.

  • Model: 비즈니스 로직 담당
  • View: 화면에 입/출력 표시 담당
  • Controller: Model과 View 제어 담당

✅ Spring MVC

스프링 MVC를 사용하면 MVC 모델을 활용해서 웹 어플리케이션을 쉽게 만들 수 있습니다. 클라이언트 요청을 받아 비즈니스 로직을 실행한 후에 그 결과를 반환하는 구조가 완성됩니다.

스프링 부트를 사용할 때 spring-boot-starter-web을 의존성에 포함시키면 스프링 MVC를 사용할 수 있습니다.

아래는 Spring MVC를 사용했을 때 동작 순서 예시입니다.

  1. 사용자: "hello" 페이지를 요청합니다.
  2. DispatcherServlet: 요청을 받습니다.
  3. 컨트롤러: "HelloController"에서 "/hello" 요청을 처리할 메소드를 찾습니다.
  4. 메소드 실행: hello() 메소드가 실행됩니다.
  5. 모델 데이터: "Hello, World!" 메시지를 모델에 추가합니다.
  6. 이름: "helloView"라는 뷰 이름을 반환합니다.
  7. 뷰 리졸버: "helloView.jsp" 파일을 찾습니다.
  8. 데이터 전달: 모델 데이터를 "helloView.jsp"에 전달합니다.
  9. 결과 표시: 브라우저에 "Hello, World!"가 표시됩니다.
@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        // 모델에 데이터를 추가합니다.
        model.addAttribute("message", "Hello, World!");
        // 뷰 이름을 반환합니다.
        return "helloView";
    }
}

서버 사이드를 중점적으로 개발할 때는 Spring MVC의 컨트롤러 기능을 사용하면 RESTful API를 제공할 수 있습니다.

뷰를 반환하는 컨트롤러는 @Controller를 사용하지만 RESTful 웹 서비스 컨트롤러는 @RestContorller를 사용합니다. 뷰가 아닌 HTTP 응답 본문으로 값이 전송됩니다. 주로 일반 텍스트나 JSON이 반환 데이터 형식으로 사용됩니다.

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
        return String.format("Hello, %s!", name);
    }
}
// 예) http://localhost:8080/hello?name=Tanjiro
// "Hello, Tanjiro!" 문자열을 결과 값으로 반환
profile
오늘의 기록은 내일의 보물

0개의 댓글