DataBase/JPA

[JPA] 데이터베이스 스키마 자동 생성

p8labs 2021. 7. 30. 20:21
728x90
반응형

데이터베이스 스키마 자동 생성

데이터베이스 스키마 자동 생성에 대해 알아본다.

해당 부분은 공부하면서 중요하다는 것을 많이 느끼게 되었다.

실무에서 망하지 않으려면 잘 익혀두어야 될것 같았다.

 

 

 

특징 및 사용

  • DDL을 애플리케이션 실행 시점에 자동 생성
    - 객체 매핑을 해두면 필요한 테이블을 다 만든다.

  • 테이블 중심 -> 객체 중심

  • 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성
    - 문자같은경우 oracle, mysql 과 속성이 다른데 알아서 맞춰 준다.

  • 이렇게 생성된 DDL은 개발 장비에서만 사용
  • 생성된 DDL은 운영서버에서는 사용하지 않거나, 적절히 다듬 은 후 사용

 

속성

  • create: 기존테이블 삭제후 다시 생성한다.
    - 어플리케이션이 수행되고 나서 기존테이블을 삭제하고 @Entity를 보고 다시 생성한다.
  • create-drop: creat와 같으나 종료시점에 테이블을 DROP 한다.
  • update: 변경분만 반영(운영 DB에는 사용하면 안된다)
  • validate: 엔티티와 테이블이 정상 매핑되었는지만 확인
  • none: 사용하지 않는다

 

 

 

속성테스트

main code

package hellojpa;

import javax.persistence.*;
import java.util.List;

public class JpaMain {
    public static void main(String[] args) {
        // persistence.xml 의 persistence-unit name="hello" 를 넘긴다.
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        // 매니저를 꺼내온다.
        EntityManager em = emf.createEntityManager();

        // 트랜잭션 얻어오고 실행한다.
        // JPA 는 트랜잭션 안에서 수행되어야 한다.
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        // exception 처리를 위해 try catch 문을 반드시 사용해야된다.
        try {

            Member member = new Member(150L,"A");

            em.persist(member);
            Member findMember1 = em.find(Member.class, 101L);
            System.out.println("findMember.id =" + findMember1.getId());
            System.out.println("findMember.name =" + findMember1.getName());


            // 커밋시 insert sql을 보낸다.
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }
        emf.close();
    }
}

 

 

 

 

create-drop 예제

<property name="hibernate.hbm2ddl.auto" value="create-drop" />​

 

로그

//create 옵션으로 기존테이블 삭제

Hibernate: 
    drop table Member if exists

// 다시 생성
Hibernate:     
    create table Member (
       id bigint not null,
        name varchar(255),
        primary key (id)
    )
    
 // select 수행
 Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_ 
    from
        Member member0_ 
    where
        member0_.id=?
    
    
    
//기존 테이블 drop
Hibernate: 
    
drop table Member if exists

Process finished with exit code 0

 

 

 

update 예제

 

<property name="hibernate.hbm2ddl.auto" value="update" />​

클래스에 새로운 필드를 추가했을때

컬럼이 추가 된다.

member class에 age 를 추가하였다.

 

Hibernate: 
    
    alter table Member 
       add column age integer not null
Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.age as age2_0_0_,
        member0_.name as name3_0_0_ 
    from
        Member member0_ 
    where
        member0_.id=?
7월 30, 2021 8:14:36 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/C:/spring/db/jpadb]

Process finished with exit code 0

 

 

 

 

 

validate 예제

 

<property name="hibernate.hbm2ddl.auto" value="validate" />​

멤버 변수에는 필드 값이 있고 

DB 에는 없을때 에러가 발생한다.

 

Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing column [age2] in table [Member]
	at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:136)
	at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:42)
	at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:89)
	at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:191)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:310)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939)
	... 4 more

Process finished with exit code 1

 

 

 

 

주의점

  •  운영 장비에는 절대 create, create-drop, update 사용하면 안된다. 
  •  개발 초기 단계는 create 또는 update 
  •  테스트 서버는 update 또는 validate 
  •  스테이징과 운영 서버는 validate 또는 none

 

 

 

DDL 생성기능

• 제약조건 추가: 회원 이름은 필수, 10자 초과X 
• @Column(nullable = false, length = 10) 
• 유니크 제약조건 추가
- @Table(uniqueConstraints = {@UniqueConstraint( name = "NAME_AGE_UNIQUE", columnNames = {"NAME", "AGE"} )}) 
• DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.

 

 

 

 

 

참고

https://www.inflearn.com/course/ORM-JPA-Basic/lecture/21695?tab=curriculum&speed=1 

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

 

728x90
반응형