[Spring] 객체와 관계형 데이터베이스

이연우·2025년 7월 28일

TIL

목록 보기
65/100

🧱 객체와 관계형 데이터베이스란?

  • 객체클래스를 통해 만들어지며 속성(field)기능(method)을 가짐
  • 관계형 데이터베이스(RDB)는 데이터를 테이블 형식으로 표현하며
    각 테이블은 열(column)행(row)으로 구성됨
  • 이 두 구조는 패러다임(생각 방식)이 달라서 충돌 발생

⚠️ 관계형 DB에 객체 저장 시 발생하는 문제점

🔁 1. 리소스별 CRUD 반복

  • Java에서는 객체를 만들고, 이걸 RDB에 저장하려면 SQL을 직접 작성해야 함

  • INSERT, UPDATE, SELECT, DELETE

  • 예를 들어, Tutor 객체 하나를 만들고 저장하려면:

INSERT INTO tutor (id, name) VALUES (1, 'wonuk');
  • 객체를 수정하면 SQL도 직접 고쳐야 함
public class Tutor {
   private String id;
   private String name;
   private Integer age; // 필드 추가
}
-- SQL도 수정
INSERT INTO tutor (id, name, age) VALUES (1, 'wonuk', 100);

❗️ 문제점: 필드가 변경될 때마다 SQL도 수동으로 바꿔야 함
→ 유지 보수 어려움

🚧 2. 객체와 SQL 간 변환 문제

  • 객체를 RDB에 저장하려면:
    • Java 객체 → SQL로 변환 (직접 매핑)
    • SQL 결과 → Java 객체로 다시 변환 (RowMapper 사용 등)

⚠️ 즉, 개발자는 SQL과 Java 코드를 양쪽 다 신경써야 함

🌪️ 3. 패러다임 불일치 문제 (Paradigm Mismatch)

  • 객체는 다음 특징을 가짐:

    • 상속 / 다형성
    • 참조 기반 관계
    • 캡슐화
  • RDB는 다음 특징을 가짐:

    • 테이블 기반 구조
    • 외래키(FK)로 관계 표현
    • 정규화 중심 설계

→ 이 차이에서 충돌이 발생함


🧬 패러다임 불일치 문제 1

🧩 상속 관계 문제

  • Java에서는 상속으로 코드를 효율적으로 재사용할 수 있음
class Person { String name; }
class Tutor extends Person { String subject; }
  • 하지만 RDB상속 개념이 없음

→ 이를 해결하려면 RDB에서는 슈퍼타입/서브타입 테이블을 별도로 구성하고 JOIN으로 조회해야 함

> Tutor 저장

> Tutor 조회

⚠️ 복잡한 SQL JOIN, 객체 매핑 작업 필수 → 개발자가 매우 귀찮아짐


🔗 연관 관계 표현의 차이

🧱 RDB는 외래키(Foreign Key) 사용

INSERT INTO tutor (id, company_id, name) VALUES ...;

테이블을 독립적으로 저장/조회할 수 있어 효율적

🧸 Java 객체는 참조(Reference) 사용

class Tutor {
  Company company;
}

→ 객체 생성 후 연관 객체 수동 세팅 필요 → 코드 복잡도 증가
→ DB는 JOIN으로 한번에 조회할 수 있지만, Java는 객체를 일일이 다시 조립해야 함


🧬 패러다임 불일치 문제 2

🕸️ 객체 그래프 탐색 문제

  • 객체는 연관된 객체를 계속 따라가며 탐색 가능해야 함
    • (product.getSupplier().getCompany())
  • 하지만 실제로는 SQL을 한 번만 실행했으면 그 결과까지만 조회 가능
Product product = repository.findById(id);
Company company = product.getSupplier().getCompany(); // ❌ 오류 발생 가능

Entity의 신뢰성 붕괴
→ 진정한 계층 분할 불가능 → 무거운 SQL 필요 → 성능 저하

🤔 객체 비교 문제

Product p1 = repo.findById(1);
Product p2 = repo.findById(1);
System.out.println(p1 == p2); // false

→ 데이터는 같지만 다른 인스턴스로 인식됨 (주소값이 다름)
참조 기반 비교가 불가능해짐

📦 Java Collection의 편리함

List<Product> list = ...;
Product p = list.get(productId);
  • 이미 메모리에 있는 객체를 가져오므로 동일성(==) 유지
  • 연관 객체도 쉽게 접근 가능 (p.getCategory())

✅ 결론 + 해결책

📍 문제 요약

  • SQL과 객체의 구조 차이로 인해 반복적인 매핑 작업
  • 필드 추가/수정 → SQL 전부 수정해야 함
  • 상속, 연관 관계, 캡슐화 등 객체의 특성은 DB와 맞지 않음

💡 해결 방법: JPA(Java Persistence API)

  • Java 객체를 마치 컬렉션처럼 다루게 해 주는 도구
    • 객체 저장: entityManager.persist(obj);
    • 객체 조회: entityManager.find(Product.class, id);
    • 연관 관계 자동 처리 (지연 로딩, 즉시 로딩 등)
    • 상속 매핑, 연관 관계 매핑, 자동 SQL 생성 등 지원

🧠 요약 정리

구분객체 지향(Java)관계형 DB(RDB)불일치
구조클래스, 참조테이블, 외래키매핑 복잡
상속지원미지원JOIN 필요
관계참조외래키수동 세팅 필요
비교주소 기반값 기반== 사용 불가
편의성컬렉션처럼 탐색 가능SQL 직접 작성 필요생산성 낮음
해결책✅ JPA 사용

0개의 댓글