김영한 강사님의 해당 강의를 통해 해당 글을 작성하였습니다.
들어가기 전에
• 객체와 테이블 매핑: @Entity
, @Table
• 필드와 컬럼 매핑: @Column
• 기본 키 매핑: @Id
• 연관관계 매핑: @ManyToOne
,@JoinColumn
@Entity
가 붙은 클래스는 JPA가 관리하는 엔티티
-> 이게 안 붙으면 테이블과 관련 x
=> JPA를 사용해서 테이블과 매핑할 클래스는 필수
• 기본 생성자가 필수이다. (파라미터x public 혹은 protected)
-> 구현해서 쓰는 기술들을 쓰려면 필요함.
• final
클래스, enum
, interface
, inner
클래스 사용X
• DB에 저장할 필드에는 final
사용 X
• 기본값 : 클래스 이름을 그대로 사용
ex) 다른 패키지에 같은 이름의 클래스가 있을 경우에 매핑까지 되어 있다면 구분해준다.
• 가급적 기본값을 사용해주자
• 구분지어줘야 할 때 씀
• 엔티티와 매핑할 테이블을 지정해준다.
위치: .properties
에 가서 hibernate.hbm2ddl.auto
속성을 설정해 줄 수 있다.
• DDL을 애플리케이션 실행 시점에 자동 생성
-> 객체 매핑을 다 해놓으면 애플리케이션이 뜰 때, 필요한 테이블을 다 만들어줌
• 테이블 중심 -> 객체 중심
• 데이터베이스 방언(ex 오라클(varchar2), mysql(varchar)등)을 무엇으로 생성했느냐에 따라서 데이터베이스에 맞는 적절한 DDL 생성
• 이렇게 생성된 DDL은 개발 장비에서만 사용
-> 절대 운영서버에서는 사용하지 (x)
=> 쓰고 싶다면 적절히 다듬은 후 사용하길...
- 운영 장비에는 절.대.
create
,create-drop
,update
를 사용하면 안된다.- 개발 초기:
create
orupdate
로 자기 로컬에서 쓰면 됨- 테스트 서버:
update
혹은validate
-> 여러 개발자들과 함께 쓰는 곳일 경우에
=> 다른 개발자가 테스트 하는데 이거로,,데이터 다 날라갈 수 있다,,- 스테이징과 운영 서버:
validate
ornone
- 직접 스크립트를 짜서 적용해보고 문제가 없으면 적용해보자
- 결론: 로컬에서만 자유롭게 쓰고
여러명이 쓰는 곳에선 저런거를 쓰지말자- '스크립트' : SQL 문
@Table
같은 경우는 Runtime에 영향을 준다.
그러나 그 외에는 보면 ddl 생성기능에 제약조건을 주는 정도이다.
ex) @Column(nullable=false, length=10)
이런 것들을 DDL 생성기능이라 한다.
=> 곧 DDL을 자동 생성할 때만 사용되고, JPA 실행 로직에 영향을 주진 않는다...
enum
타입을 매핑할 때 쓰임.ORDINARL
은 사용하지 말자ordinal : enum
의 순서를 DB에 저장
STRING: enum
의 이름을 DB에 저장
LocalDate
, LocalDateTime
등의 타입이 더 많이 쓰인다..주로 긴 글에서 많이 사용함.
• 데이터베이스 BLOB, CLOB 타입과 매핑
• @Lob
에는 지정할 수 있는 속성이 없다.
• 매핑하는 필드 타입이 문자면 CLOB 매핑, 나머지는 BLOB 매핑
- CLOB: String
, char[]
, java.sql.CLOB
- BLOB: byte[]
, java.sql. BLOB
• 필드 매핑X , 데이터베이스에 저장X, 조회X
• 매핑을 하기 싫으면 이것을 쓰면 됨
• 주로 메모리상에서만 임시로 어떤 값을 보관하고 싶을 때 사용
• @Id
• @GeneratedValue
이렇게 2가지로 나뉘고 쓰인다.
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
이들은 매핑 방법을 통해서 나뉜다.
• 직접 할당: @Id
만 사용
• 자동 생성(@GeneratedValue
)
• IDENTITY: 데이터베이스에 위임, MYSQL
• SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, ORACLE
• @SequenceGenerator 필요
• TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
• @TableGenerator 필요
• AUTO: 방언에 따라 자동 지정, 기본값
• 기본 키 생성을 데이터베이스에 위임
• 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용
(예: MySQL의 AUTO INCREMENT)
• JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL 실행
• AUTO INCREMENT는 데이터베이스에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있음
• IDENTITY 전략은 em.persist()
시점에 즉시 INSERT SQL 실행하고 DB에서 식별자를 조회
=> 나는 모르겠고 DB 니가 알아서 해라
내가 id에 값을 넣어서는 안된다. null로 날라오면 DB에서 값을 세팅해주어야 한다.
id값을 언제 알 수 있냐? DB에 값이 딱 들어왔을 때 알 수 있다.
영속성 컨텍스트에서 PK 값을 모르니까 울며 겨자먹기로
em.persist()
를 호출하는 시점에 바.로. DB에 INSERT 쿼리를 날린다.-> JPA가 그 값을 들고 와서 바로 세팅해주고 영속성 컨텍스트의 PK 값으로 쓰게 된다.
단점: 모아서 하는게 불가능
• '값'을 순서대로 생성하는 특별한 데이터베이스 오브젝트 -> 대표적으로 '오라클'이 있음.
ex) 오라클, PostgreSQL, DB2, H2 데이터베이스
@SequenceGenerator()
을 어노테이션으로 설정하여 세세하게 설정
- 이용:
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "적용하고자 하는 시퀀스 전략")
call next value for
: DB에 에 다음 값 내놔라!
여기서 얻은 값을 em.persist()로 영속성 컨텍스트에 값을 넣으려고 딱 하는데
어 너? 시퀀스네? DB한테 값을 얻어와야겠네?
DB에서 값을 얻어와서 객체에 딱 id를 넣어주는 것이다!
=> 아직 INSERT 쿼리는 안 날라갔음 (왜? PK 값만 얻고 필요하면 버퍼링도 해줘야 하니까!!!)
=> 영속성 컨텍스트에 쌓여있음
이러고 PK 값을 얻고, 실제 커밋하는 시점에 INSERT 쿼리가 호출하게 된다.
특징: 버퍼링이 가능
이들을 이용해 성능 최적화에 쓰임.
=> 자꾸 next.call()로 가져오면 성능 문제가 있을 수 있어
=> 그러니 그냥 난 DB를 50개 미리 땡겨올래!
=> 50에 거의 다 와가네 next.call() 1번 호출 -> 그러면 다시 한 번 더 51~100까지 땡겨오고
=> 곧 DB에 next call로 미리 세팅해놓고(50개씩) - 나는 메모리에서 1씩 쓰는 것이다.
여러 웹서버들이 있어도, 동시성 문제 없이 다양한 문제들이 해결되는 장점이 있다.
• 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략
• 장점: 모든 데이터베이스에 적용 가능
• 단점: 성능
allocationSize: 미리 값을 올려두는 방식임.
- 동시 호출을 하더라도 본인이 숫자를 미리 확보하엿기 때문에 문제x