-
JPA 프로그래밍 - 1 (스프링 데이터 JPA - 2)Programming/Spring Data JPA 2020. 4. 30. 19:03728x90
1. 개요 (기본)
- 의존성 추가 (spring data JPA와 관련된 빈들이 모두 등록됨)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
- application.properties 추가
spring.datasource.url=jdbc:postgresql://localhost:5432/springdata spring.datasource.username=hongchan spring.datasource.password=pass spring.jpa.hibernate.ddl-auto=create //update, validate // 개발할 때는 create, 이후에는 validate 사용을 권장! // update는 스키마 수정 시 지저분해질 수 있는 우려가 있음! 조심해서 사용
- 도메인 Account 객체 생성 @Entity
@Entity public class Account { @Id @GeneratedValue private Long id; private String username; private String password; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsernmae() { return username; } public void setUsernmae(String usernmae) { this.username = usernmae; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
- JPA API 사용하기
@Component @Transactional // persist 사용 시 트랜잭션으로 처리해야 함 public class JpaRunner implements ApplicationRunner { @PersistenceContext EntityManager entityManager; // JPA API에서 가장 핵심적인 것 @Override public void run(ApplicationArguments args) throws Exception { Account account = new Account(); account.setUsernmae("jiyun"); account.setPassword("1234"); entityManager.persist(account); } }
- Hibernate API 사용하기
@Component @Transactional public class JpaRunner implements ApplicationRunner { @PersistenceContext EntityManager entityManager; @Override public void run(ApplicationArguments args) throws Exception { Account account = new Account(); account.setUsernmae("jiyun2"); account.setPassword("hibernate"); Session session = entityManager.unwrap(Session.class); // 핵심적인 API session.save(account); } }
2. 엔티티 맵핑
@Entity
- 객체 세상에서 부르는 이름 (보통 클래스와 같은 이름을 사용하기 때문에 잘 변경하지 않음)
@Table
- 릴레이션 세상에서 부르는 이름
- @Entity의 이름이 기본 값
- 테이블의 이름은 SQL에서 쓰임
@Id
- 엔티티의 PK를 맵핑할 때 사용
@GeneratedValue
- PK의 생성 방법을 맵핑하는 애노테이션
@Column
- 보통 생략되어 있고, 추가적으로 명시할 때 사용
- (nullable = false, unique = true)
@Temporal
- Date, Calender
@Transient
- 컬럼으로 맵핑하고 싶지 않은 멤버에 추가
- 실행되는 SQL 문을 확인하는 설정 추가
spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true
3. Value 타입 맵핑
- Account 엔티티 타입 안에 있는 멤버들(id, username, password)
- 기본 타입, Composite Value 타입, Collection Value 타입
Composite Value 타입 맵핑
- @Embadable
- @Embadded
- @AttributeOverrides
- @AttributeOverride
@Embeddable public class Address { private String city; private String state; private String street; }
@Entity public class Account { @Id @GeneratedValue private Long id; ... @Embedded private Address address; }
// 실행된 SQL create table account ( id int8 not null, city varchar(255), state varchar(255), street varchar(255), password varchar(255), username varchar(255), primary key (id) )
4. 1대다 맵핑
- 관계에는 항상 두 엔티티가 존재함
- 둘 중 하나는 그 관계의 주인이고, 다른 쪽은 종속된 쪽이다.
- 해당 관계의 반대쪽 레퍼런스를 가지고 있는 쪽이 주인
@ManyToOne
- Study 가 이 관계에서 주인이 됨. (단방향에서는 관계를 정의한 쪽이 주인)
- 종속된 쪽의 PK를 FK로 설정함
(Getter Setter 생략)
- Account.java
@Entity public class Account { @Id @GeneratedValue private Long id; private String username; private String password; }
- Study.java
@Entity public class Study { @Id @GeneratedValue private Long id; private String name; @ManyToOne private Account owner; }
@OneToMany
- Account가 관계의 주인이 됨 (단방향에서는 관계를 정의한 쪽이 주인)
- Join 테이블 생성 'account_studies'
- Account.java
@Entity public class Account { @Id @GeneratedValue private Long id; private String username; private String password; @OneToMany private Set<Study> studies = new HashSet<>(); }
- Study.java
@Entity public class Study { @Id @GeneratedValue private Long id; private String name; }
양방향 관계
- 기본적으로 FK를 가진쪽(@ManyToOne)이 주인이 됨!
- @OneToMany 쪽에 mappedBy를 사용해 관계를 맺고 있는 필드를 설정해주어야 함!! (주인한테 관계를 설정해야 DB에 반영이 됨)
- Account.java의 addStudy, removeStudy 메소드 처럼 구현하여 보통 양쪽에 데이터를 넣거나 삭제시켜 일치시킴.
-> 주인인 쪽에만 설정하면 DB에 반영이 되지만 양방향을 고려하여 양쪽에 데이터를 일치시킴
- Account.java
@Entity public class Account { @Id @GeneratedValue private Long id; private String username; private String password; @OneToMany(mappedBy = "owner") private Set<Study> studies = new HashSet<>(); ... public void addStudy(Study study) { this.getStudies().add(study); study.setOwner(this); // 주인에 설정 } public void removeStudy(Study study) { this.getStudies().remove(study); study.setOwner(null); // 주인에 설정 } }
- Study.java
@Entity public class Study { @Id @GeneratedValue private Long id; private String name; @ManyToOne private Account owner; }
인프런 백기선님 '스프링 데이터 JPA’ 강의를 듣고 정리한 내용입니다.
728x90'Programming > Spring Data JPA' 카테고리의 다른 글
스프링 데이터 Common - Web (스프링 데이터 JPA - 6) (0) 2021.01.01 스프링 데이터 Common - 2 (스프링 데이터 JPA - 5) (0) 2021.01.01 스프링 데이터 Common - 1 (스프링 데이터 JPA - 4) (0) 2021.01.01 JPA 프로그래밍 - 2 (스프링 데이터 JPA - 3) (0) 2021.01.01 관계형 데이터베이스와 ORM (스프링 데이터 JPA - 1) (0) 2020.04.30