관계형 데이터베이스와 ORM

김승규·2024년 2월 26일

백엔드 개발자의 기본: 데이터를 잘 저장하고 잘 가져오는 것

영속성이란?

  • 데이터를 잘 읽고 잘 쓰는 것. 날아가지 않도록 유지하는 것이다.

H2 database

  • 자바 기반, 오픈 소스, 관계형 데이터베이스
  • 실제 실무에서는 안쓴다. 아주 작은 테스트용 프로그램 짤 때만 사용

jdbc


DataSource

  • 커넥션 반환

Connection

  • Statement vs PreparedStatement
    • PreparedStatement는 미리 쿼리를 파싱해놓고, 똑같은 쿼리가 실행되면 이전에 파싱된 결과를 이용하여 실행한다.
  • close
    • 반드시 해야한다.

Connection Pool

장점

  • 데이터베이스에 Connection 을 생성할때 소요되는 시간 및 자원을 줄일 수 있습니다.
  • Connection 수를 제한 할 수 있어 과다한 접속으로 인한 서버 자원 고갈을 예방합니다.
    • 수가 제한되어 있어 서비스가 커질 때 제한이 됨으로 단점이 될 수 있다.(스케일업 or 풀 제한으로 해결)
  • 메모리 영역에서 Connection 을 관리하기 때문에 클라이언트가 데이터베이스 작업을 빠르게 진행할 수 있습니다.

구현체 종류

  • Apache Commons DBCP : 레거시 프로젝트에서 많이 사용
  • Tomcat DBCP : 공공쪽 관련된 SI나 큰 기업에서 많이 사용
  • HikariCP : 스프링 부트에서 많이 사용

Spring Framework JdbcTemplate

  • JDBC API 기반
  • JdbcTemplate 을 사용하면 지금까지 Jdbc 를 사용한 코드에서 많은 부분을 Spring Framework 가 대신 처리해 줍니다.
    (X가 한다는 뜻)

jdbc

dataSource

    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:~/spring-jpa;DATABASE_TO_UPPER=false;"
                + "INIT=RUNSCRIPT FROM 'classpath:/script/schema.sql'");
        dataSource.setUsername("sa");
        dataSource.setPassword("");

        dataSource.setInitialSize(10);
        dataSource.setMaxTotal(10);
        dataSource.setMinIdle(10);
        dataSource.setMaxIdle(10);

        dataSource.setMaxWaitMillis(1000);

        dataSource.setTestOnBorrow(true);
        dataSource.setTestOnReturn(true);
        dataSource.setTestWhileIdle(true);
//        dataSource.setValidationQuery("select 1");

        return dataSource;
    }

일반적으로 위 4개의 값을 통일하는 것을 추천한다.

JPA mapping Entity

어노테이션

  • @Entity : JPA가 관리할 객체임을 명시
  • @Table : 맵핑할 DB 테이블 명 지정
  • @Id : 기본 키(PK) 맵핑
  • @Column : 필드와 컬럼 맵핑 (생략 가능)
  1. 기본 생성자 필수
  2. public class(인터페이스나 enum은 안된다)
  3. final 변수는 안된다.

필드와 컬럼 맵핑

@Column

  • 객체 필드를 컬럼에 맵핑
  • 생략 가능

@Temporal

  • 날짜 타입 맵핑
public enum TemporalType {
    DATE, 
    TIME, 
    TIMESTAMP
}

cf.) java 8 date/time (LocalTime, LocalDate, ZonedDateTime) 타입은 @Temporal을 붙이지 않는다.

@Transient

  • 특정 필드를 컬럼에 맵핑하지 않을 경우에 지정

복합키

  • @IdClass
  • @EmbeddedId / @Embeddable
    • 가져올 때 차이가 있다. 큰 차이는 없음

@IdClass 를 이용한 복합 Key 지정

추상화는 덜 되어 있지만 get 한 번에 가져올 수 있다.

@Getter
@Setter
@ToString
@NoArgsConstructor
@Entity
@Table(name = "OrderItems")
@IdClass(OrderItem.PrimaryKey.class)
public class OrderItem {
    @Id
    @Column(name = "order_id")
    private Long orderId;

    @Id
    @Column(name = "line_number")
    private Integer lineNumber;

    @Column(name = "item_id")
    private Long itemId;

    @Column
    private int quantity;

    @AllArgsConstructor
    @NoArgsConstructor
    @Getter@Setter
    @EqualsAndHashCode
    public static class PrimaryKey implements Serializable {
        private Long orderId;

        private Integer lineNumber;

    }
}

@EmbeddedId / @Embeddable를 이용한 복합 Key 지정

추상화가 잘 되어 있지만, 가져올때 getPk().get~을 해야한다.

@Getter
@Setter
@ToString
@NoArgsConstructor
@Entity
@Table(name = "OrderItems")
public class OrderItem2 {
    @EmbeddedId
    private PrimaryKey pk;

    @Column(name = "item_id")
    private Long itemId;

    @Column
    private int quantity;

	@AllArgsConstructor
    @NoArgsConstructor
    @Getter@Setter
    @EqualsAndHashCode
    public static class PrimaryKey implements Serializable {
        @Column(name = "order_id")
        private Long orderId;

        @Column(name = "line_number")
        private Integer lineNumber;

    }
}

복합 Key Class 제약조건

  • PK 제약조건을 그대로 따름

PK 제약 조건

  • The primary key class must be public and must have a public no-arg constructor.
  • The primary key class must be serializable.
  • The primary key class must define equals and hashCode methods.
profile
꿈꾸는 리얼리스트 개발자 김승규입니다.

0개의 댓글