Spring Data JDBC

InSeok·2022년 9월 9일
0

TIL

목록 보기
31/51

Spring Data JDBC

목차


  1. JDBC
  2. Spring Data JDBC
  3. Aggregate
  4. 엔티티, 서비스, 리포지토리 구현

배운 내용


**JDBC(Java Database Connectivity)**

  • Java 기반의 애플리케이션에서 사용하는 데이터 액세스 기술의 기본이 되는 저수준(low level) API

JDBC 동작 흐름

Untitled

**JDBC API 사용 흐름**

  1. JDBC 드라이버 로딩

JDBC 드라이버는 DriverManager라는 클래스를 통해서 로딩

  1. Connection 객체 생성

    DriverManager를 통해 데이터베이스와 연결되는 세션(Session)인 Connection 객체를 생성

  2. Statement 객체 생성

Statement 객체는 작성된 SQL 쿼리문을 실행하기 위한 객체로써 객체 생성 후에 정적인 SQL 쿼리 문자열을 입력으로 가진다.

  1. Query 실행

생성된 Statement 객체를 이용해서 입력한 SQL 쿼리를 실행

  1. ResultSet 객체로부터 데이터 조회

실행된 SQL 쿼리문에 대한 결과 데이터 셋입니다.

  1. ResultSet 객체 Close, Statement 객체 Close, Connection 객체 Close

JDBC API를 통해 사용된 객체들은 사용 이후에 사용한 순서의 역순으로 차례로 Close

**Connection Pool**

  • 애플리케이션 로딩 시점에 Connection 객체를 미리 생성해두고 애플리케이션에서 데이터베이스에 연결이 필요할 경우, 미리 만들어 둔 Connection 객체를 사용
  • 데이터베이스 Connection을 미리 만들어서 보관하고 애플리케이션이 필요할 때 이 Connection을 제공해주는 역할 (Connection 관리자)
  • 스프링부트 - HikariCP를 기본 DBCP로 채택

**SQL 중심 기술**

  • MyBatis
  • Spring JDBC

ORM (Object-Relational Mapping)

  • SQL 쿼리문을 직접적으로 작성하기 보다 객체(Object) 중심의 데이터 액세스 기술
  • JPA(Java Persistence API)
  • **Spring Data JDBC**

**Spring Data JDBC**

  • 애플리케이션의 규모가 상대적으로 크지 않고, 복잡하지 않을 경우 생산성 높음
  • public interface MessageRepository extends CrudRepository<Message, Long>
    • CrudRepository는 데이터베이스에 CRUD(데이터 생성, 조회, 수정, 삭제) 작업을 진행하기 위해 Spring에서 지원해주는 인터페이스
    • Message : 엔티티 클래스 객체에 담긴 데이터를 데이터베이스 테이블에 CRUD
    • Long : 식별자를 의미하는 @Id 애너테이션이 붙어있는 멤버 변수의 데이터 타입

Entity 클래스

  • 클래스명은 데이터베이스의 테이블명에 해당한다.
  • @Id애너테이션을 추가한 멤버 변수 → 고유 식별자 역할 , DB의 Primary key로 지정한 컬럼에 해당
  • ORM(Object-Relational Mapping)에서는 객체의 멤버 변수와 데이터베이스 테이블의 컬럼이 대부분 1대1로 매핑
  • 테이블의 식별자(Primary key)‘message_id’ 컬럼에 AUTO_INCREMENT 설정이 되어 있으므로 ‘message_id’ 컬럼에 값을 입력하지 않더라도 데이터가 저장이 될 때 마다 자동으로 포함이 된다
  • application.properties 또는 application.yml 파일의 설정 정보 등록을 통해 데이터베이스 설정, 데이터베이스의 초기화 설정 등의 다양한 설정을 할 수 있다.

H2 DB에 테이블 생성

spring:
  h2:
    console:
      enabled:truepath: /h2
  datasource:
    url: jdbc:h2:mem:test
  sql:
    init:
      schema-locations: classpath*:db/h2/schema.sql   // (1) 테이블 생성 파일 경로

**DDD(Domain Driven Design)**

  • 도메인 주도 설계
  • 도메인이란? 현실 세계에서 접하는 업무의 한 영역

**애그리거트(Aggregate)**

  • 비슷한 범주의 연관된 업무들을 하나로 그룹화 해놓은 그룹

**애그리거트 루트(Aggregate Root)**

  • 하나의 애그리거트를 대표하는 도메인
  • 데이터베이스의 테이블 간 관계로 보자면, 애그리거트 루트는 부모 테이블이 되고, 애그리거트 루트가 아닌 다른 도메인들은 자식 테이블이다.
  • 애그리거트 루트(Aggregate Root)의 기본키 정보를 다른 도메인들이 외래키 형태로 가지고 있다
  • A 테이블의 기본키를 B 테이블이 가지고 있다면 A는 부모 테이블이 되고, B는 자식 테이블이 됩니다. B인 자식 테이블이 가지고 있는 A 테이블의 기본키를 외래키라고 한다.
  • 데이터베이스 테이블 간의 관계는 외래키를 통해 맺어지지만 클래스끼리 관계는 객체의 참조
    를 통해 맺어진다

**애그리거트 객체 매핑 규칙**

  1. 모든 엔티티 객체의 상태는 애그리거트 루트를 통해서만 변경할 수 있다.(도메인 규칙의 일관성을 유지목적)
    1. 애그리거트 루트가 나머지 모든 엔티티에 대한 객체를 직간접적으로 참조 할 수 있다
  2. 하나의 동일한 애그리거트 내에서의 엔티티 객체 참조
    1. 동일한 하나의 애그리거트 내에서는 엔티티 간에 객체로 참조한다.
  3. 애그리거트 루트 대 애그리거트 루트 간의 엔티티 객체 참조
    • 애그리거트 루트 간의 참조는 객체 참조 대신에 ID로 참조한다.
    • 1대1과 1대N 관계일 때는 테이블 간의 외래키 방식과 동일하다.
    • N대N 관계일 때는 외래키 방식인 ID 참조와 객체 참조 방식이 함께 사용된다.

**엔티티 구현**

  • @Table애너테이션을 추가하지 않으면 기본적으로 클래스명이 테이블의 이름과 매핑
  • @Table(”NAME”)와 같이 테이블 이름을 변경가능

1대N 관계의 애그리거트 루트 간 ID 참조

  • AggregateReference클래스로 한번 감싸주는 방법으로 구현
  • AggregateReference 클래스는 테이블의 외래키처럼 다른 객체의 ID 값을 참조할 수 있도록 해준다.
    • ex) private AggregateReference<Member, Long> memberId

N대N의 관계의 애그리거트 루트 간 ID 참조

  • 우선, N대N 관계를 1대N, N대1 관계로 풀어줄 엔티티가 중간에 하나 필요
  • 이 엔티티가 Order 클래스와 동일한 애그리거트에 있다 → 동일한 애그리거트 내에서는 객체 참조를 사용
  • @MappedCollection 애너테이션의 역할
    • ex)@MappedCollection(idColumn = "ORDER_ID")
    • 엔티티 클래스 간에 연관 관계를 맺어주는 정보를 의미
    • idColumn 애트리뷰트는 자식 테이블에 추가되는 외래키에 해당되는 컬럼명
      을 지정
  • N 대 N 관계에서는 AggregateReference로 Id를 감쌀 필요가없다.

**서비스, 리포지토리 구현**

리포지토리(Repository)

  • 데이터 액세스 계층에서 데이터베이스와 상호작용하는 역할을 하는 인터페이스

쿼리 메서드(Query Method)

  • Spring Data JDBC에서는 쿼리 메서드를 이용해서 SQL 쿼리문을 사용하지 않고 데이터베이스에 질의가능
  • find + By + SQL 쿼리문에서 WHERE 절의 컬럼명 + (WHERE 절 컬럼의 조건이 되는 데이터)
  • Spring Data JDBC에서는 Optional을 지원하기 때문에 리턴값을 Optional로 래핑할 수 있다
  • findByxxxx에서 사용하는 컬럼명은 반드시 엔티티 클래스의 멤버 변수명을 적어주어야 한다

@Query애너테이션

  • 개발자가 직접 쿼리문을 작성해서 질의를 할 수 있도록 해준다.

  • ex) @Query("SELECT * FROM COFFEE WHERE COFFEE_ID = :coffeeId")

    • :coffeeIdfindByCoffeeId(Long coffeeId)coffeeId변수 값이 채워지는 동적 쿼리 파라미터(named parameter)
  • Spring Data JDBC에서 내부적으로 Java의 리플렉션 기술과 Proxy 기술을 이용해서 Repository 인터페이스의 구현 클래스 객체를 생성해준다.

  • 비즈니스 로직에서 어떤 검증이 필요한 로직은 별도의 로직으로 추출해서 검증 메서드에 검증을 해달라고 요청하는 것이 코드의 간결성과 가독성을 향상시킨다.

  • Spring Data JDBC에서는 @Id 애너테이션이 추가된 엔티티 클래스의 멤버 변수 값이 0 또는 null이면 신규 데이터라고 판단하여 테이블에 insert 쿼리를 전송합니다.

  • 반면에 @Id 애너테이션이 추가된 엔티티 클래스의 멤버 변수 값이 0 또는 null이 아니라면 이미 테이블에 존재하는 데이터라고 판단하여 테이블에 update 쿼리를 전송

  • findAll() 메서드의 리턴값은 Iterable<T> 이다. 알맞은 타입으로 캐스팅필요!

  • orElseThorow()는 객체가 null 이 아니라면 해당 객체를 리턴하고 null이라면 예외를 던집니다

profile
백엔드 개발자

0개의 댓글