Jpa를 사용해서 테이블과 매핑할 class를 @Entity를 필수로 붙여야하며, @Entity가 붙은 class를 entity라고 부른다.
@Entity 적용 시 다음과 같은 전제조건을 만족해야한다.
기본생성자
final class , enum , interface , inner class가 아니여야 한다.
저장할 필드에 final 키워드가 붙으면 안된다.
Jpa는 다양한 mapping annotation을 지원하는데 , 크게 4가지로 분류될 수 있다.
객체와 테이블 매핑 : @Entity , @Table
기본 키 매핑 : @Id
Field와 Column 매핑 : @Column
연관관계 매핑 ex) @ManyTone , @JoinColumn
기본키 매핑 전략
DB id값을 client측에서 넘겨줄 수 있겠지만, 인조키의 경우 DB vendor에서 생성할 수도 있다. DB vendor 마다 기본키를 생성하는 방식이 다르다, 예를 들면 oracle에서는 sequence 객체를 만들고, mysql에서는 auto_increment기능을 사용한다.
Java Persistence API (JPA)는 Java 진영의 ORM (Object relational mapping ) 기술 표준으로서 (API 표준 명세로 , JPA 자체가 구현체는 아니다. ) , JDBC API를 추상화해 application과 JDBC 사이에서 동작한다.
Jpa를 사용하려면 그 구현체를 선택해야하는데, 구현체는 hibernate , EclipseLink , DataNuclues가 존재하며 이중에서 hibernate가 가장 대중적이다.
Java 코드를 작성하고 compile하면 bytecode (.class) 가 생성된다. 이 bytecode를 실행해주는 역할이 Jvm의 역할이다. byte code는 최종적으로 machine code (native code)로 변경되서 실행되는데 이는 CPU에 종속적이다. Jvm은 OS별로 구현체가 여러개 있어, Java source 코드는 운영체제와는 독립적으로 작성될 수 있도록 해준다.
Jvm은 bytecode (.class)를 실행해주는데, 사실 Java 이외에도 .class file이 생성되는 타 프로그래밍 언어들을 실행할 수 있다 예를 들면 Kotlin ,Scala 가 있다.
Stack Generic Type으로 변경할 경우 , Client에서 Stack에서 꺼낸 객체를 형변환할 필요가 없으며 동시에 ClassCastException 이 나지 않는 장점을 갖는다.
Item 28 에서는 Generic 사용시 배열보다 리스트를 고려하라고 권고는 하였으나 Generic type 안에서 List를 사용하는게 항상 가능하지도 않고, Java가 기본 타입으로 List를 제공하지 않으므로 성능 향상 목적으로 기본 타입인 배열을 사용하기도 한다.
배열은 공변(covariant) 인 반면 Generic은 불공변(invariant) 이다.
Sub class가 Super class의 하위 class라고 가정하면 배열 Sub[]는 Super[]의 하위 타입이 된다. 반면에 서로 다른 타입인 Type1과 Type2가 있을떄 Generic인 List<Type1> List<Type2> 은 아무 계층관계도 가지지 않는다.
1 2 3 4 5 6 7
// Array Object[] longs = new Long[1]; longs[0] = "타입이 다름에도 컴파일에러가 나지 않습니다."; //ArrayStoreException
// Generic List<Object> ol = new ArrayList<Long>(); // compile Error
배열은 type으로 인해 runtime Exception이 발생할 수 있는 반면, generic인 compile 경고를 먼저 띄워준다.
배열은 실체화 된다.
배열은 runtime 에도 원소의 타입을 인지하고 확인한다, 예를 들면 Long 배열에 String을 넣으려고 하면 runtime에 이를 확인하고 예외를 발생시킨다. 반면 generic은 runtime에 타입을 소거한다 (type erasure). 원소의 타입을 compile time에만 검사하며 , runtime에는 모른다.