ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA 프로그래밍 - 1 (스프링 데이터 JPA - 2)
    Programming/Spring Data JPA 2020. 4. 30. 19:03
    728x90

    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

    댓글

Designed by Tistory.