본문 바로가기

Spring/JPA & Hibernate

Entity Mapping

반응형
  • @Entity가 붙은 클래스는 JPA가 관리, 엔티티라 한다. 
  • JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수
  • 주의
    기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자) 
    final 클래스, enum, interface, inner 클래스 사용X 
    저장할 필드에 final 사용 X
  • 속성: name 
    JPA에서 사용할 엔티티 이름을 지정한다.  
    기본값: 클래스 이름을 그대로 사용(예: Member) 
    같은 클래스 이름이 없으면 가급적 기본값을 사용한다.

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

  • application loading 시점에 자동 DDL 생성
  • 테이블 중심 -> 객체 중심
  • 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성
  • 이렇게 생성된 DDL은 개발 장비에서만 사용
  • 생성된 DDL은 운영서버에서는 사용하지 않거나, 적절히 다듬은 후 사용

hibernate.hbm2ddl.auto 옵션


<property name="hibernate.hbm2ddl.auto" value="create" />
  • create: 기존테이블 삭제 후 다시 생성 (DROP + CREATE) 
  • create-drop: create와 같으나 종료시점에 테이블 DROP (DROP + CREATE..UPDATE... + DROP) 
  • update: 변경 부분만 반영(운영DB에는 사용하면 안됨)
  • validate: 엔티티와 테이블이 정상 매핑되었는지만 확인
  • none: 사용하지 않음

필드와 컬럼 매핑

 


@Entity
public class Member {

	@Id
	private Long id;

	@Column( name = "name" )
	private String username;

	private Integer age;

	@Enumerated( EnumType.STRING )
	private RoleType roleType;

	@Temporal( TemporalType.TIMESTAMP )
	private Date createdDate;

	@Temporal( TemporalType.TIMESTAMP )
	private Date lastModifiedDate;

	@Lob
	private String description;

	@Transient
	private int temp;

	public Member() {
	}

	public Long getId() {
		return this.id;
	}

	public void setId( final Long id ) {
		this.id = id;
	}

	public String getUsername() {
		return this.username;
	}

	public void setUsername( final String username ) {
		this.username = username;
	}

	public Integer getAge() {
		return this.age;
	}

	public void setAge( final Integer age ) {
		this.age = age;
	}

	public RoleType getRoleType() {
		return this.roleType;
	}

	public void setRoleType( final RoleType roleType ) {
		this.roleType = roleType;
	}

	public Date getCreatedDate() {
		return this.createdDate;
	}

	public void setCreatedDate( final Date createdDate ) {
		this.createdDate = createdDate;
	}

	public Date getLastModifiedDate() {
		return this.lastModifiedDate;
	}

	public void setLastModifiedDate( final Date lastModifiedDate ) {
		this.lastModifiedDate = lastModifiedDate;
	}

	public String getDescription() {
		return this.description;
	}

	public void setDescription( final String description ) {
		this.description = description;
	}

	public int getTemp() {
		return this.temp;
	}

	public void setTemp( final int temp ) {
		this.temp = temp;
	}

}

 

@Enumerated( EnumType.STRING)으로 설정해줘야.. default : ORDINAL


Member member1 = new Member();
member1.setId( 1L );
member1.setUsername( "A" );
member1.setRoleType( RoleType.USER );

Member member2 = new Member();
member2.setId( 2L );
member2.setUsername( "B" );
member2.setRoleType( RoleType.ADMIN );

em.persist( member1 );
em.persist( member2 );

tx.commit();

 

기본 키 매핑

 

기본 키 매핑 어노테이션

  • 직접 할당: @Id 
  • 자동 생성: @GeneratedValue

IDENTITY


@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
  • 기본 키 생성을 데이터베이스에 위임
  • 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용

    (예: MySQL의 AUTO_ INCREMENT) 
  • JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL 실행
  • AUTO_ INCREMENT는 데이터베이스에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있음
  • IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL 실행하고 DB에서 식별자를 조회

 


Member member1 = new Member();
member1.setUsername( "A" );
member1.setRoleType( RoleType.USER );

Member member2 = new Member();
member2.setUsername( "B" );
member2.setRoleType( RoleType.ADMIN );

System.out.println( "=================" );
em.persist( member1 );
em.persist( member2 );
System.out.println( "member1 id: " + member1.getId() );
System.out.println( "member2 id: " + member2.getId() );
System.out.println( "=================" );
tx.commit();

Insert 결과

 JDBC Drive 의 내부에 Insert 쿼리로 db에 생성한 값을 return을 받아 select 쿼리를 실행하지 않아도 알 수 있음. 

SEQUENCE

  • 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트(예: 오라클 시퀀스) 
  • 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용
  • db에는 50개씩 미리 올려 놓고, 메모리 상에서 1씩 쓰는 전략
    allocationSize (default: 50)
    시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용됨)
    데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 한다 
    -> next call 호출 횟수를 줄일 수 있다.

 

 


@Entity
@SequenceGenerator( name = "member_seq_generator",
	sequenceName = "member_seq", //매핑할 데이터베이스 시퀀스 이름
	initialValue = 1, allocationSize = 50 )

public class Member {

	@Id
	@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "member_seq_generator" )
	private Long id;

	@Column( name = "name" )
	private String username;

	private Integer age;

	@Enumerated( EnumType.STRING )
	private RoleType roleType;

	@Temporal( TemporalType.TIMESTAMP )
	private Date createdDate;

	@Temporal( TemporalType.TIMESTAMP )
	private Date lastModifiedDate;

	@Lob
	private String description;

	@Transient
	private int temp;

	public Member() {
	}
}

 

TABLE 

  • 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략
  • 장점: 모든 데이터베이스에 적용 가능
  • 단점: 성능

@Entity
@TableGenerator(
	name = "MEMBER_SEQ_GENERATOR",
	table = "MY_SEQUENCES",
	pkColumnValue = "MEMBER_SEQ", allocationSize = 50 )  
public class Member {

	@Id
	@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR" )
	private Long id;

	@Column( name = "name" )
	private String username;

	private Integer age;

	@Enumerated( EnumType.STRING )
	private RoleType roleType;

	@Temporal( TemporalType.TIMESTAMP )
	private Date createdDate;

	@Temporal( TemporalType.TIMESTAMP )
	private Date lastModifiedDate;

	@Lob
	private String description;

	@Transient
	private int temp;


}

 

반응형

'Spring > JPA & Hibernate' 카테고리의 다른 글

@MappedSuperclass  (0) 2020.01.09
연관관계 맵핑  (0) 2019.12.19
준영속 상태  (0) 2019.12.18
플러시  (0) 2019.12.18
영속성 컨텍스트  (0) 2019.12.18