스프링 데이터 JPA-01.관계형 데이터베이스와 자바, ORM


관계형 데이터베이스와 자바

JDBC

  • DataSource / DriverManager
  • Connection
  • PreparedStatement

SQL

  • DDL
  • DML

JDBC 사용의 문제점

  • SQL을 실행하는 비용이 비싸다.(오래 걸린다)
  • SQL이 데이터베이스 마다 다르다.
  • 스키마를 바꿀때마다 많은 코드를 수정해야 한다.
  • 반복적인 코드가 너무 많다.
  • 당장은 필요가 없는데 언제 쓸 줄 모르니까 미리 다 읽어와야 하나… (필요가 없더라도 다 읽어야 한다)

JDBC 사용

try(Connection connection = DriverManager.getConnection(url, username, password)) {
    System.out.println("Connection created: " + connection);
    String sql = "INSERT INTO ACCOUNT VALUES(1, 'keesun', 'pass');";
    try(PreparedStatement statement = connection.prepareStatement(sql)) {
        statement.execute();
    }
}

도메인 모델 사용

Account account = new Account(“keesun”, “pass”);
accountRepository.save(account);

실습

의존성 추가

<dependency>
   <groupId>org.postgresql</groupId>
   <artifactId>postgresql</artifactId>
</dependency>

PostgreSQL 설치 및 서버 실행 (docker)

docker run -p 5432:5432 -e POSTGRES_PASSWORD=pass -e POSTGRES_USER=jaeuk -e POSTGRES_DB=springdata --name postgres_boot -d postgres

docker exec -i -t postgres_boot bash

su - postgres

psql springdata

데이터베이스 조회
\list

테이블 조회
\dt

쿼리
SELECT * FROM account;

ORM 개요

JDBC 대신 도메인 모델 사용하려는 이유

  • 객체 지향 프로그래밍의 장점을 활용 가능
  • 각종 디자인 패턴
  • 코드 재사용
  • 비즈니스 로직 구현 및 테스트 편리함.

ORM은 애플리케이션의 클래스와 SQL 데이터베이스의 테이블 사이의 맵핑 정보를 기술한 메타데이터를 사용하여, 자바 애플리케이션의 객체를 SQL 데이터베이스의 테이블에 자동으로 (또 깨끗하게) 영속화 해주는 기술.

In a nutshell, object/relational mapping is the automated (and transparent) persistence of objects in a Java application to the tables in an SQL database, using metadata that describes the mapping between the classes of the application and the schema of the SQL database. Java Persistence with Hibernate, Second Edition

장점유일한 단점
생산성학습비용
유지보수성 
성능 
밴더 독립성 

부가적인 설명

우리가 어떠한 한 트랜잭션 안에서 account를 저장을 했다.
그 안의 값들을 변경할 때 만약 password를 3번 변경을 하고 저장을 한다.
만약 sql 이라면 3번 변경이니까 update 쿼리만 3번 사용한다.

만약 하이버네이트나 jpa같은 orm을 썼다면 실제 sql은 한번만 실행이 된다.
객체와 데이터베이스간 캐시가 있어서 변경사항을 감지하고 이 변경사항을 반영해야 말아야 하나 결정을 한 후
정말로 디비에 변경을 해야하는 그 시점에만 반영을 한다.

한 트랜잭션 내에서 값을 바꿨지만 jpa가 훨씬 더 성능이 좋다.
정말 작은 예시 중에 하나이고 성능 최적화를 위한 다양한 방법을 제공해 준다.

또한 db를 바꾸더라도 코드는 전혀 영향이 없다.
유일한 단점은 학습비용 발생, 생각보다 어럽다.
하지만 장점이 훨씬 더 많음.
특히 성능에 관련된 부분 이점이 정말 크다. 혹시라도 하이버네이트가 성능이 더 부족하다면 학습이 모자란 것.

추천 서적
김영한 - 자바 ORM표준 JPA프로그래밍

ORM 패러다임 불일치

객체를 릴레이션에 맵핑하려니 발생하는 문제들과 해결책

밀도(Granularity) 문제

객체릴레이션
다양한 크기의 객체를 만들 수 있음.테이블
커스텀한 타입 만들기 쉬움.기본 데이터 타입 (UDT는 비추)

서브타입(Subtype) 문제

객체릴레이션
상속 구조 만들기 쉬움.테이블 상속이라는게 없음.
다형성상속 기능을 구현했다 하더라도 표준 기술이 아님.

식별성(Identity) 문제

객체릴레이션
레퍼런스 동일성 (==)주키 (primary key)
인스턴스 동일성 (equals() 메소드) 

관계(Association) 문제

객체릴레이션
객체 레퍼런스로 관계 표현.외래키(foreign key)로 관계 표현.
근본적으로 ‘방향’이 존재 한다.‘방향’이라는 의미가 없음. 그냥 Join으로 아무거나 묶을 수 있음.
다대다 관계를 가질 수 있음태생적으로 다대다 관계를 못만들고, 조인 테이블 또는 링크 테이블을 사용해서 두개의 1대다 관계로 풀어야 함.

데이터 네비게이션(Navigation)의 문제

객체릴레이션
레퍼런스를 이용해서 다른 객체로 이동 가능.하지만 그런 방식은 릴레이션에서 데이터를 조회하는데 있어서 매우 비효율적이다.데이터베이스에 요청을 적게 할 수록 성능이 좋다. 따라서 Join을 쓴다.
콜렉션을 순회할 수도 있음.하지만, 너무 많이 한번에 가져오려고 해도 문제다.그렇다고 lazy loading을 하자니 그것도 문제다. (n+1 select)





© 2019. by jaeuk