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명이 접근 중이면 접근할 수 없도록 막아버리는 방법
- 뒤늦게 읽은 사람은 읽기 전용으로만 접근할 수 있도록 하는 방법
- 모두 접근과 수정을 허용하되 가장 마지막에 수정한 결과를 반영하는 방법 : dirty write
장애 대응
- 중요한 데이터를 저장하고 관리하는 공간인 만큼 장애에 대한 대응에 신경 써야함
- 데이터 다중화 및 백업 : 물리적으로 한 공간만 사용한다면, 그 공간이 에러 발생이나 데이터 소실 되었을 때 어떻게 할 것인가? 미리 대응해야함
- 비용은 많이 들지만 돌이킬 수 없는 상황에 놓여지는 것보다 훨씬 값싼 비용을 치루는 것이라 생각해야함
보안
- 클라이언트는 데이터베이스의 존재를 모르도록 하는 것 뿐만 아니라 보안에도 각별하게 신경써야함
- 데이터베이스에 원본 그대로 저장하지않고 암호화해서 저장하기도 함 : key값은 따로 저장
- 데이터베이스에 저장된 데이터가 유출되었을 때를 대비하여 중요한 데이터의 경우 평문으로 저장하지않고 암호화된 상태로 저장하는 것이 좋음
데이터베이스 종류
- 관계형 데이터베이스(RDBMS)
- 객체지향 데이터베이스
- XML 데이터베이스
- NoSQL(not only sql) 데이터베이스