[코드로 배우는 스프링 부트 웹 프로젝트] 스프링 부트(Spring Boot) 01

hidihyeonee·2025년 2월 10일
0
post-thumbnail

2025.02.10 작성

OS : Window
개발환경: IntelliJ IDEA
개발언어: Java
프레임워크: Spring Boot


ORM

객체(Object)와 관계형 데이터베이스(Relational Database) 간의 매핑을 자동화하는 기술.

✔ ORM이란?
데이터베이스의 테이블을 객체(Object)로 매핑하여 SQL 없이 자바 객체로 데이터를 다룰 수 있도록 해주는 기술.
JDBC + SQL을 직접 작성하는 것이 아니라, ORM을 사용하여 더 객체지향적으로 데이터베이스를 조작.

✔ ORM을 쓰면 좋은 점?
✅ SQL 의존성 감소 → 객체 중심의 코드 작성 가능.
✅ DB 변경 시 유지보수 쉬움 → 테이블 구조 변경 시 코드 변경 최소화.
✅ 생산성 향상 → SQL 작성 없이 save(), findById() 등의 메서드로 조작 가능.

JPA (Java Persistence API)

자바에서 ORM을 사용하기 위한 표준 인터페이스.

✔ JPA란?
ORM을 구현하기 위한 자바 표준 API.
직접 SQL을 작성하는 것이 아니라, 객체와 관계형 데이터베이스를 자동으로 매핑.
Hibernate, EclipseLink, OpenJPA 같은 구현체들이 있음.

✔ JPA를 사용하면 좋은 점?
✅ SQL을 직접 쓰지 않아도 됨 → save(), findById() 같은 메서드 제공.
✅ DB 변경에 유연함 → SQL을 직접 수정할 필요 없음.
✅ JPQL 사용 가능 → 객체 중심의 쿼리 작성.

Hibernate

JPA의 대표적인 구현체(라이브러리).

✔ Hibernate란?
JPA를 구현한 가장 유명한 ORM 프레임워크.
SQL 대신 자바 객체로 DB를 조작할 수 있도록 지원.
JPA의 표준 API를 따르면서, 추가 기능도 제공함.

Hibernate vs JPA vs ORM 비교

📌 정리하면

ORM은 객체와 DB를 매핑하는 개념 자체.
JPA는 ORM을 위한 자바 표준 API.
Hibernate는 JPA의 구현체 중 하나.
--> JPA는 ORM 기술을 제공하는 표준 인터페이스고, Hibernate는 이를 구현한 라이브러리!


1. Memo 엔티티 클래스 (Memo.java)

@Entity
@Table(name = "tbl_memo")
@ToString
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Memo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long mno;

    @Column(length = 200, nullable = false)
    private String memoText;
}

@Entity: 해당 클래스가 JPA 엔티티(Entity, 즉 데이터베이스 테이블과 연결된 클래스)임을 선언.
데이터베이스의 테이블과 매핑됨.

@Table(name = "tbl_memo"): tbl_memo라는 이름의 테이블과 연결됨.

@ToString: toString() 메서드를 자동으로 생성해줌.

@Getter: 모든 필드에 대한 Getter 메서드를 자동으로 생성.

@Builder: Memo 객체를 빌더 패턴으로 생성할 수 있도록 지원.

@AllArgsConstructor: 모든 필드를 포함하는 생성자 자동 생성.

@NoArgsConstructor: 기본 생성자 자동 생성.

@Id: 기본 키(primary key) 지정.

@GeneratedValue(strategy = GenerationType.IDENTITY):

  • mno 필드가 자동 증가(AUTO_INCREMENT) 하도록 설정.
  • IDENTITY 전략을 사용하면, 데이터베이스에서 자동으로 증가된 값을 생성.
  • 새로운 데이터가 추가될 때마다 mno 값이 자동으로 1씩 증가됨.

@Column(length = 200, nullable = false):

  • memoText 컬럼의 길이를 200자로 제한.
  • nullable = false로 설정하여 반드시 값이 있어야 함.

2. MemoRepositoryTests 테스트 코드 (MemoRepositoryTests.java)

주입(Injection)이란?
"주입"이란 외부에서 객체를 자동으로 넣어주는 것(할당해주는 것).
스프링 프레임워크에서는 의존성 주입(Dependency Injection, DI)이라고도 부름.

1. 주입이 필요한 이유

👉 주입이 없으면? (직접 객체 생성)
보통 우리가 어떤 객체를 사용하려면 new 키워드로 직접 생성해야 함.

public class MemoService {
    private MemoRepository memoRepository;

    public MemoService() {
        this.memoRepository = new MemoRepository();  // 직접 객체 생성
    }
}

문제점

  • MemoService가 MemoRepository의 구체적인 구현에 직접 의존하게 됨.
  • 만약 MemoRepository를 다른 클래스로 바꿔야 하면 MemoService도 수정해야 함 → 유지보수 어려움.

2. 주입(Injection)을 사용하면?

이제 외부에서 객체를 넣어주는 방식(주입).

public class MemoService {
    private MemoRepository memoRepository;

    // 외부에서 MemoRepository를 주입받음 (생성자 주입)
    public MemoService(MemoRepository memoRepository) {
        this.memoRepository = memoRepository;
    }
}

개선된 점

  • MemoService는 MemoRepository가 어떻게 만들어지는지 몰라도 됨!
  • MemoRepository를 다른 클래스로 쉽게 변경할 수 있음.
  • 객체 생성을 직접 하지 않으므로 테스트하기 쉬워짐.

3. 스프링에서 자동으로 주입하는 방법

스프링에서는 @Autowired를 사용해서 객체를 자동으로 주입할 수 있음.

@Service
public class MemoService {

    @Autowired  // MemoRepository를 자동으로 주입
    private MemoRepository memoRepository;

    public void saveMemo() {
        Memo memo = new Memo();
        memo.setMemoText("스프링 주입 테스트");
        memoRepository.save(memo);
    }
}

🛠 동작 방식

  • 스프링이 실행될 때 MemoRepository 객체를 자동으로 생성함.
  • @Autowired를 보고 MemoService에 MemoRepository 객체를 자동으로 넣어줌.
  • 개발자는 new 키워드를 사용하지 않아도 스프링이 알아서 주입해줌.

MemoRepositoryTests.java

@SpringBootTest
public class MemoRepositoryTests {

    @Autowired
    private MemoRepository memoRepository;

    @Test
    public void testClass() {
        System.out.println(memoRepository.getClass().getName());
    }

    @Test
    public void testInsertDummies() {
        IntStream.rangeClosed(1, 100).forEach(i -> {
            Memo memo = Memo.builder().memoText("Sample..." + i).build();
            memoRepository.save(memo);
        });
    }
}

@SpringBootTest
Spring Boot의 테스트 환경을 제공하여 ApplicationContext를 로드함.
스프링 컨텍스트에서 MemoRepository를 자동으로 주입받을 수 있음.

@Autowired private MemoRepository memoRepository;
MemoRepository를 스프링이 자동으로 주입하여 사용할 수 있도록 함.

testClass()

@Test
public void testClass() {
    System.out.println(memoRepository.getClass().getName());
}
  • memoRepository가 실제로 어떤 클래스의 객체로 생성되는지 출력.
  • Spring Data JPA는 memoRepository의 구현체를 자동 생성하므로 이를 확인하는 용도.

testInsertDummies()

@Test
public void testInsertDummies() {
    IntStream.rangeClosed(1, 100).forEach(i -> {
        Memo memo = Memo.builder().memoText("Sample..." + i).build();
        memoRepository.save(memo);
    });
}
  • IntStream.rangeClosed(1, 100)을 사용하여 1부터 100까지 반복 실행.

  • Memo.builder().memoText("Sample..." + i).build();
    - memoText 필드에 "Sample...1", "Sample...2", ..., "Sample...100" 값을 넣어 Memo 객체를 생성.

  • memoRepository.save(memo);
    - 생성한 Memo 객체를 DB에 저장.

testClass() 실행 시

intelliJ

HeidiSQL

testSelect()

@Test
public void testSelect() {
    Long mno = 99L;  // 조회할 Memo의 ID 값 설정
    Optional<Memo> result = memoRepository.findById(mno);  // ID로 조회

    System.out.println("----------------------");

    if (result.isPresent()) {  // 결과가 존재하면
        Memo memo = result.get();  // Memo 객체 가져오기
        System.out.println(memo);  // Memo 객체 출력
    }
}

profile
벨로그 쫌 재밌네?

0개의 댓글