반응형
📝@Entity, @Id, @GeneratedValue, @Temporal, @Lob
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // IDENTITY 전략
// @GeneratedValue(strategy = GenerationType.SEQUENCE) // SEQUENCE 전략
@Column(name="member_id")
private Long id;
private String name;
private int age;
private String address; // 필드만 추가해주면 끝
// @Enumerated(EnumType.ORDINAL) // enum 타입 매핑 [숫자] (금지)
@Enumerated(EnumType.STRING) // enum 타입 매핑 [문자] (사용 OK)
private CategoryEnum name;
// 날짜 타입 매핑 [아래 LocalDateTime을 쓰면 알아서 YYYYMMDDHHMMSS 설정]
@Temporal(TemporalType.DATE)
private Date date;
private LocalDateTime createDate
@Lob // BLOB, CLOB 매핑
private String description;
}
- @Entity
- JPA에서 영속성 컨텍스트가 관리할 테이블이라는 의미이다.
- @Id
- 해당 필드를 PK로 지정하겠다는 의미이다.
- @GeneratedValue
- PK AutoIncrement설정이다. IDENTITY로 설정할지 SEQUENCE로 지정할지 정할 수 있다.
- @Temporal
- 날짜 필드라는 걸 알리는 의미이다.
- @Lob
- BLOB, CLOB타입이라는 걸 알리는 의미이다.
📝@JoinColumn, @ManyToOne, @OneToMany, @OneToOne, @ManyToMany
@Entity
public class Member {
@Id // PK로 설정할 컬럼
@GeneratedValue
private long id;
@Column(nullable = false, length = 10)
private String name;
@ManyToOne
@JoinColumn(name = "TEAM_ID") // Team 테이블[클래스]에 연결할 필드명을 알려주세요
// (JoinColumn은 FK가 있는 테이블에 들어간다)
private Team team;
}
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
}
- @JoinColumn
- 연결할 테이블에 필드를 지정한다
- @ManyToOne
- 다대일 관계로 연결하겠다는 의미
- @OneToMany
- 일대다 관계로 연결하겠다는 의미
- @OneToOne
- 일대일 관계로 연결하겠다는 의미
- @ManyToMany (사용 X)
- 다대다 관계로 연결하겠다는 의미 (다대다 관계는 무조건 다대일로 풀어내야한다)
📝@Inheritance, @DiscriminatorColumn, @DiscriminatorValue
@Inheritance(strategy = InheritanceType.JOINED) // 조인 전략
@DiscriminatorColumn
@Entity
public class Item {
@Id
@GeneratedValue
private long id;
private String name;
private int price;
}
@Entity
// @DiscriminatorValue("this is movie")
public class Movie extends Item{
private String director;
private String actor;
}
public class Main {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Movie movie = new Movie();
movie.setName("바람과 함께 사라지다");
movie.setPrice(10000);
movie.setActor("이민호");
movie.setDirector("봉준호");
em.persist(movie);
tx.commit();
}catch (Exception e){
e.printStackTrace();
}finally{
emf.close();
em.close();
}
}
}
@Inheritance
관계형 데이터베이스에 상속관계라는 걸 JPA에서 표현했다
@DiscriminatorColumn
해당 어노테이션을 사용 안 하면 DTYPE이 따로 안 보이는데 이걸 명시적으로 표현해주는 어노테이션 어느 자식이 UPSERT 되어서 그런지 잘 모르니 해당 어노테이션을 사용하는게 좋다
@DiscriminatorValue
해당 어노테이션을 사용하면 DTYPE에 들어갈 걸 명시적으로 지정할 수 있다.
📝@MappedSuperclass
@MappedSuperclass
public abstract class BaseEntity {
@Column(name = "create_date") // 부모 클래스에서 컨트롤 가능
private LocalDateTime localDateTime;
private LocalDateTime modi_date;
}
@Entity
public class Book extends BaseEntity{
@Id
@GeneratedValue
private long id;
private String name;
private String author;
private String ISBN;
}
Inheritance와 차이가 있는 점은 Inheritance은 부모 자식 테이블 따로따로 들어가게 되는데 MappedSuperclass의 경우 필드만 공유하고 하나의 테이블로 만들어진다.
📝@NamedQuery, @Query
@Entity
@NamedQuery(
name="Member.findByUsername", // Key
query="select m from Member m where m.username = :username" // Value
)
public class Member {
@Id @GeneratedValue
@Column(name = "member_id")
private Long id;
private String username;
private int age;
}
public interface MemberRepository extends JpaRepository<Member, Long> {
/** ----- 방법1 (@Query) ----- **/
@Query(name ="Member.findByUsername")
List<Member> findByUsername(@Param("username") String username);
/** ----- 기본 예제 ----- **/
@Query("select m from Member m where m.username = :username and m.age = :age")
List<Member> findUser(@Param("username") String username, @Param("age") int age);
}
조건절 조회하는 임의의 쿼리가 필요할 때 Entity에 @NamedQuery를 이용해 JpaRepository에서 {키:값} 형태로 찾아 사용이 가능하다
이 방법보단 JpaRepository에서 바로 @Query를 이용해 바로 작성하는 걸 더 많이 사용한다
📝@Modifying
public interface MemberRepository extends JpaRepository<Member, Long> {
@Modifying(clearAutomatically = true)
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);
}
Update한 후에 Update 항목을 조회하는 경우가 있을 때 영속성 컨텍스트 캐시를 날리고 데이터 조회하기 때문에 디비에서 조회하게 되고 데이터의 정합성을 맞춘다
📝@EntityGraph
public interface MemberRepository extends JpaRepository<Member, Long> {
@EntityGraph(attributePaths = {"team"})
@Query("select m from Member m")
// 위에 코드는 EntityGraph + Query로 아래와 같은 코드이다. (team Fetch Join)
// @Query("select m from Member m left join fetch m.team")
List<Member> findMemberEntityGraph();
}
패치조인을 더 쉽게할 수 있도록 스프링 데이터 JPA에서 제공해준다.
엔터티 라이프 사이클 컨트롤 어노테이션 (@PrePersist, @PreUpdate, @PreRemove, @PostPersist, @PostUpdate, @PostRemove, @PostLoad)
@PrePersist : 새로운 엔티티에 대해 persist가 호출되기 전
@PreUpdate : 엔티티 업데이트 작업 전
@PreRemove : 엔티티가 제거되기 전
@PostPersist : 새로운 엔티티에 대해 persist가 호출된 후
@PostUpdate : 엔티티가 업데이트된 후
@PostRemove : 엔티티가 삭제된 후
@PostLoad : Select조회가 일어난 직후에 실행
반응형