2020-4-11 스프링 Data common (2) JPA 시작 및 엔티티매핑
JPA 시작
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jimmydb?serverTimezone=UTC
spring.datasource.username=id
spring.datasource.password=pw
spring.jpa.hibernate.ddl-auto=create => 앱을 실행할때마다 다 초기화해서 새로 만든다. 계속 유지하고 싶으면 update
spring.jpa.hibernate.ddl-auto=validate // 실제로는 validate가 좋다. create는 새로만들겠다.
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
- 하이버네이트가 구동시에 체크. 개발시에는 create or update 실제 배포에서는 validate
- 특정 MySQL버전부터는 timezone을 설정해줘야한다. 그래서 serverTimezone=UTC로 설정
- Hibernate.dialect 옵션을 통해 MySQL 5.x 버전을 사용한다고 명시한다. 이 옵션을 변경하면 다른 데이터베이스로 변경하기 용이하다.
@Entity
public class Account {
@Id @GeneratedValue
private Long id;
private String username;
private String password;
}
- @Entity는 DB에 Account에 테이블에 매핑된다는 것을 가르쳐준다.
- field들은 기본적으로 테이블에 다 매핑이 된다. @Entity때문. @Column이 생략된거나 마찬가지.
- JPA를 사용하는데 필요한 BEAN들이 자동으로 주입받는다.
@Component
@Transactional
public class JpaRunner implements ApplicationRunner {
@PersistenceContext
EntityManager entityManager;
@Override
public void run(ApplicationArguments args) throws Exception {
Account account = new Account();
account.setUsername("jimmy");
account.setPassword("hibernate");
Session session = entityManager.unwrap(Session.class);
session.save(account);
// entityManager.persist(account);
}
}
- Spring에서 ApplicationContext가 핵심이듯이 JPA에서는 EntityManager가 핵심이다. 엔티티매니저를 통해 데이터베이스를 영속화 할 수 있다.
- 영속화 : 데이터베이스에 저장한다.
- 엔티티매니저와 관련된 모듈과 오퍼레이션들은 동일한 트랜잭션에서 동작해야한다. @Transactional를 통해 클래스, 메서드에 적용한다.
엔티티매핑
javax.persistence에서 오는 어노테이션을 써야한다.
- 테이블 매핑하는 방법
- 어노테이션
- XML => 최근에는 거의 보기 힘들다.
@Entity
- 이름을 줄 수 있지만 기본적으로 클래스와 같은 이름을 사용하기 때문에 바꾸지 않는다. 엔티티의 이름은 하이버네이트에서 적용되는 이름이고 실제 테이블 이름은 @Table에 이름을 붙여서 사용한다. **하지만 엔티티에 아무런 설정을 안하면 클래스이름으로 설정이 된다. 문제가 생길때가 있다. 어떤 디비에서는 User, 특정 키워드를 등록 못하는경우가 있다. **
@Id
- main key를 설정. 모든 Primitive와 Wrapper 타입을 지원.
- primitive를 쓸것이냐 wrapper를 쓸것이냐가 논쟁이있다. long(primitive)면 기본적으로 0으로 세팅된다. DB에서 만들어진 0과 내가 직접만든 0을 구분하기 위해 Wrapper를 쓰는게 좋다.
@GenerateValue
- 주키를 자동매핑.
- DB에 따라 자동생성하는 전략을 취한다.
- 기본전략은 AUTO
- TABLE, IDENTITY, SEQUENCE 중 하나.
@Column
- 모든 엔티티에 들어있는 멤버변수에는 @Column이 생략
-
Column에는 다양한 옵션들이 있다(nullable, unique etc.. )
@Temporal
- JPA 2.1에서는 Date, Calander밖에 안된다. 2.2이후로는 java8이후의 데이트 라이브러리들을 지원한다.
@Temporal(TemporalType.DATE)
DATE
TIME
TIMESTAMP
@Trasient
- 컬럼으로 매핑하고 싶지 않은 멤버에 설정
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
- show-sql을 하면 콘솔에 sql을 찍어준다. 가독성이 안좋아서 format_sql도 함께 넣어준다.
- 개발시에는 true하고. 운영시에 보이게 하기 위해서는 하이버네이트보다는 로거에서 쓴다.
엔티티타입과 Value타입 구분
- 식별자가 있어야 하는가
- 독립적으로 존재해야 하는가
- value : 다른 엔티티에 종속적인가
Composit Value 타입 매핑
- @Embadable
- @Embadded
- @AttributeOverrides
- @AttributeOverride
@Entity
public class Account {
@Id @GeneratedValue
private Long id;
.
.
.
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "street", column = @Column(name = "home_street"))
})
private Address homeAddress;
}
@Embeddable
public class Address {
private String street;
private String city;
private String state;
private String zipcode;
}
// DB table
create table account (
id bigint not null,
create_date date,
city varchar(255),
state varchar(255),
home_street varchar(255),
zipcode varchar(255),
password varchar(255),
username varchar(255),
primary key (id)
) engine=MyISAM
- Embeddable을 붙여서 의존관계를 설정한다. Account에는 homeAddress, OfficeAddress 등이 존재할 수 있으므로 @AttributeOverrides를 설정한다.
- @Embeddable한 클래스를 실행하면 테이블이 따로 생성되는 것이 아니라 상위?클래스에 테이블 열에 같이 생성된다.
Value타입 종류
- 기본타입(String, Date, Boolean…)
- Compose Value타입
- Collection Value타입
- 기본타입컬렉션
- 컴포짓 타입의 콜렉션
Written on April 11, 2020