콘텐츠로 이동

2021 06 25

2021-06-25

JPA

  • 참고: https://www.youtube.com/playlist?list=PL9mhQYIlKEhfpMVndI23RwWTL9-VL-B7U
  • 왜 JPA 배우지? - "객체를 관계형 DB에 저장" 1. SQL 중심의 개발... - SQL 의존적인 개발하게 됨 - Dao에서 반환된 객체 자체를 100% 믿고 사용할 수 있나? 2. 패러다임 불일치 - 객체와 관계형 DB는 다른 사상을 가짐 - 객체는 상속 O, DB는 상속 X - 객체의 연관관계는 단방향성, DB의 연관관계는 양방향성 - 객체의 데이터 타입은 객체, DB의 데이터 타입은 객체ID - 객체를 자바 컬렉션에 저장하듯 저장할 수는 없을까?
  • JPA의 장점 - 신뢰할 수 있는 Entity - 동일성 보장 - Collection을 쓰듯 DB 저장 - JPA 성능 최적화 가능 - 1차 캐시 도입 - Transaction을 지원하는 쓰기 지연 - 지연로딩, 즉시로딩
  • JPA 실습 - 여러 Database 방언 지원 - resources/META-INF/persistence.xml에서 사용할 DB를 등록해주자
    <?xml version="1.0" encoding="UTF-8" ?>
    <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.2">
      <persistence-unit name="hello">
          <properties>
              <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
              <property name="javax.persistence.jdbc.user" value="sa"/>
              <property name="javax.persistence.jdbc.password" value=""/>
              <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
              <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
    
              <property name="hibernate.show_sql" value="true"/>
              <property name="hibernate.format_sql" value="true"/>
              <property name="hibernate.use_sql_comments" value="true"/>
              <property name="hibernate.id.new_generator_mappings" value="true"/>
    
              <property name="hibernate.hbm2ddl.auto" value="create"/>
          </properties>
      </persistence-unit>
    </persistence>
    

    - EntityManagerFactory?

    public class Main {
        public static void main(String[] args) {
            final EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
            final EntityManager em = emf.createEntityManager();
            final EntityTransaction tx = em.getTransaction();
            tx.begin();
    
            try {
                final Member member = new Member();
                member.setName("안녕하세요");
                member.setMemberType(MemberType.USER);
                member.setDate(new Date());
    
                em.persist(member);
                tx.commit();
            } catch (Exception e) {
                tx.rollback();
            } finally {
                em.close();
            }
    
            emf.close();
        }
    }
    

      - Persistence.xml을 읽어 설정 정보 조회... Persistence 생성
      - Persistence.createEntityManagerFactory를 통해 EntityManagerFactory 생성
          - EntityManagerFactory는 하나만 생성해 어플리케이션 전체에서 공유
      - EntityManagerFactory를 통해 EntityManager를 생성
          - JPA 모든 Data 변경은 트랜잭션 내부에서 실행
          - EntityManager는 쓰레드 간 교류 XXX
    

    - DB 스키마 자동 생성해보기 - - persistence.xml에서 다음과 같은 프로퍼티를 추가해주자 - value에 따라,,, - create: 기존 테이블 삭제 후 재생성 - create-drop: create와 동일 + 종료 시 테이블 drop - update: 변경문만 반영 - validate: Entity-Table 매핑 확인 - none: 사용 X - 개발 초기: create/update - 테스트 서버: update/validate - 스테이징/운영: validate/none - 어노테이션을 통한 Entity - Table 매핑 java @Entity //자 Entity 생성합니다 public class Member { @Id //PK로 이걸 쓸거에요 @GeneratedValue(strategy = GenerationType.AUTO) //DB가 설정한 기본값으로 증가시킵니다 private Long id; //이거는 DB에서 USERNAME 컬럼과 매핑해주세요 //NOTNULL, 최대 20자! @Column(name = "USERNAME", nullable = false, length = 20) private String name; private int age; //Date넣어줄 거에요 @Temporal(TemporalType.DATE) private Date date; //Enum 넣을 때 String으로 넣을게요! @Enumerated(EnumType.STRING) private MemberType memberType; }

      - 식별자 Mapping 방법
          - IDENTITY: DB에 위임
          - SEQUENCE: DB sequence object 사용
          - TABLE: 키 생성용 테이블 사용
          - AUTO: 기본값