TIL - 0626

JPA

  • DDL : 테이블 생성, 변경 등의 쿼리, 테스트 서버에서는 자동 변경하도록 설정하는 것이 괜찮지만 실서버에서는 그러면 안됨
  • 스키마 : 데이터베이스 테이블 정보를 집약해서 하나 만들어두고, 레퍼런스 삼아서 JPA(정확히는 구현체) 작업을 함
  • 키(pk) 생성할 때 : 대리키를 사용하라
  • 키 생성 전략(자동 - 대리키) : 엔티티에 키를 할당하는 전략, 데이터베이스 마다 각각 다른 전략을 취하고 있음
    • IDENTITY : 키 생성부터 할당까지 데이터베이스에서 함, auto_increment 전략을 사용하려면 해당 전략을 사용해야함
    • SEQUENCE : 키 생성은 데이터베이스 시퀀스(키 생성 전용 객체)로 하고, 키 할당은 JPA에서 엔티티에 해줌
    • TABLE : 키 생성(키 생성 전용 테이블을 사용해서 생성함)부터 할당까지 JPA에서 함
    • 직접 할당 : 키 생성부터 할당까지 직접
    • AUTO : 각 데이터베이스가 지원하는 전략에 맞게 키 할당 전략을 선택해서 키를 할당함
  • DBMS마다 다른 키 생성 전략
    • MySQL, PostgreSQL, SQL Server, DB2, H2 : IDENTITY
    • PostgreSQL, H2, DB2 : SEQUENCE
  • 항상 생각해야할 부분은 여러 데이터베이스에 맞게 JPA가 맞춰줌 : JPA는 데이터베이스와 상호작용할 때 표준화된 방법을 사용할 수 있도록 만들어진 방법
  • primitive type 인 경우 @NotNull이 자동으로 붙음
  • @Temporal을 생략하면 timestamp로
  • @Lob : 타입을 보고 알아서 데이터베이스 타입을 지정해줌(문자열)
    • CLob(문자 타입),BLOB(오라클),
    • 벤더사마다 다르니깐 하나의 이름으로 문자열(TEXT)길이에 따라 타입을 지정함
  • 엔티티는 식별자 값으로 접근(@Id)

java-ims

jackson 사용하면서 주의할 점과 생각해봐야할 것

  • json으로 변환할 데이터는 선언된 타입과 똑같은 getMethod를 가지고 있어야함
    • 그렇지않으면 DataBindingException 발생 : 오랜시간 동안 찾음…..삽질 ㅠ
    • Enum, LocalDateTime 똑같은 문제 때문에 안되던 것 : 데이터 타입의 문제가 아니라 getMethod을 String으로 반환 중이여서 그랬음

@RestController 처리하기

  • RestController를 사용할 때 응답 데이터를 어떻게 보내줄 것인가?
    • Issue에 대한 처리를 RestController로 받고 응답해줄 때 body에는 Issue만, 헤더에 Issue와 관련된 URI를 세팅하는 것이?
  • RestController와 Controller를 같이 개발할 때 예외처리를 어떻게 해줄 것인가?
    • 스프링에서 @RestControllerAdvice와 @ControllerAdvice를 제공하고있음 : RestController의 경우 예외 발생하면 @RestControllerAdvice부터 찾아감

DTO

  • DTO가 사용될 때를 생각하면서 추상화하기
    • 요청 -> Jackson이 자동변환(DTO로 받기) : 생성자를 만들 때 이떄 필요한만큼 필드만 생성자의 파라미터로…
public CommentDto() {
}

public CommentDto(String comment) {
    this.comment = comment;
}

public Comment _toComment() {
    if (writer == null && issue == null) {
        return new Comment(comment);
    }
    return new Comment(comment, writer, issue);
}

계층 구조(순차 처리)

  • 서비스 계층에서 모든 처리가 완료되면 컨트롤러 계층에서 할 수 있는 일이 생김
    • 서비스 계층에서 레포지토리에 요청을 날려서 엔티티 Id가 할당된 상태 , writer, issue DI 완료 -> 댓글 관련 요청 URI를 가져올 수 있음
/* Comment.java */
@Override
public String generateUri() {
    return String.format("/api/issues/%d/comments/%d", issue.getId(), getId());
}

JPA

  • json fetchType
    • @ManyToOne : 기본적으로 fetchType Eager임 - 데이터가 단 하나라면? 굳이? 아닌가 하긴 오브젝트라면 불러와야할 데이터가 있으니깐 오브젝트 하나라고 해서 그냥 Eager를 쓰면 안되겠음

데이터베이스

데이터베이스 정의

  • 데이터를 관리하는 시스템
    • 관리하는 방식에 따라 시스템 이름이 붙여짐 : RDBMS, NoSQL

요구되는 기본적인 것들

기본 기능

  • 검색 / 등록, 수정 삭제(데이터베이스 갱신) 기능 지원
  • 속도 또한 빨라야함 : 데이터베이스에 요청하고 요청에 대한 처리 후 응답하는 작업을 빠르게 해야함
  • 복구는 데이터베이스가 제공하는 것이 아니라 데이터베이스를 활용하는 기술자들이 백업 및 복구 전략을 정해서 사용해야함

데이터 고유함을 보장

  • 데이터는 고유해야함
  • 식별자(primary key, 레코드 1개 당 고유적으로 가지고 있는 값)로 데이터를 구분함
    • 자연키 : 유의미한 데이터를 가지고 키로 사용함 - 위험성이 있음(데이터가 계속해서 변경된다면?)
    • 대리키 : 유의미한 데이터를 키로 사용하지않고, 키 역할을 하는 데이터를 생성해서 키로 활용

동시성 제어

  • 동시성 제어 : 동시적으로 시스템 접근하는 것을 고려해야함 - 데이터(갱신) 무결성
    • 같은 데이터(고유)에 대해 두 명 이상의 사용자가 접근해서 갱신하려고 한다면? 안돼
  • 동시성 제어 방법
    1. 1명이 접근 중이면 접근할 수 없도록 막아버리는 방법
    2. 뒤늦게 읽은 사람은 읽기 전용으로만 접근할 수 있도록 하는 방법
    3. 모두 접근과 수정을 허용하되 가장 마지막에 수정한 결과를 반영하는 방법 : dirty write

장애 대응

  • 중요한 데이터를 저장하고 관리하는 공간인 만큼 장애에 대한 대응에 신경 써야함
    • 데이터 다중화 및 백업 : 물리적으로 한 공간만 사용한다면, 그 공간이 에러 발생이나 데이터 소실 되었을 때 어떻게 할 것인가? 미리 대응해야함
  • 비용은 많이 들지만 돌이킬 수 없는 상황에 놓여지는 것보다 훨씬 값싼 비용을 치루는 것이라 생각해야함

보안

  • 클라이언트는 데이터베이스의 존재를 모르도록 하는 것 뿐만 아니라 보안에도 각별하게 신경써야함
  • 데이터베이스에 원본 그대로 저장하지않고 암호화해서 저장하기도 함 : key값은 따로 저장
    • 데이터베이스에 저장된 데이터가 유출되었을 때를 대비하여 중요한 데이터의 경우 평문으로 저장하지않고 암호화된 상태로 저장하는 것이 좋음

데이터베이스 종류

  • 관계형 데이터베이스(RDBMS)
  • 객체지향 데이터베이스
  • XML 데이터베이스
  • NoSQL(not only sql) 데이터베이스