<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
<persistence-unit name="myjpa">
<properties>
<!-- 접속할 DB에 대한 속성(필수 속성) -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpadb"/>
<!-- DB 방언에 대한 속성 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect" />
<!-- 추가 설정 옵션 -->
<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" />
<!-- Schema 자동 생성 옵션 -->
<!--<property name="hibernate.hbm2ddl.auto" value="create" />-->
</properties>
</persistence-unit>
</persistence>
먼저 전체 완성된 persistence.xml 형식은 위와 같다.
그렇다면 한 부분씩 뜯어보면서 어떤 property가 어떤 역할을 하는지 알아보자.
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
~~~
</persistence>
설정 파일임을 알리는 태그이다.
<persistence-unit name="myjpa">
<properties>
~~~
<properties>
</persistence-unit>
영속성 유닛을 등록하는 방법으로 태그 안에 영속성 유닛(persistence-unit)에 대한 여러 가지 설정이 들어갈 수 있다.
영속성 유닛 1개는 여러 개의 Property를 가지고 있어 내가 원하는 EntityManagerFactory의 설정 값들을 넣어줄 수 있다.
일반적으로 연결할 DB 하나당 1개의 persistence-unit을 등록하는 경우가 많다.
예를 들어, name="mysql"인 영속성 유닛에는 MySQL DB 설정을, name="oracle"인 영속성 유닛에는 Oracle DB 설정을 넣어줌으로써 1개의 설정 파일에 여러 개의 설정들을 입력해 줄 수 있다.
나중에 Persistence 객체를 통해 EntityManagerFactory를 생성할 때 영속성 유닛에 붙인 name(고유한 이름) 값을 넣어줌으로써 여러 설정들 중 내가 적용시키고 싶은 설정을 먹여줄 수 있다.
(ex) mysql 설정을 먹이고 싶은 경우
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mysql");
// 영속성 유닛 중 name="mysql"인 영속성 유닛이 MySQL DB 접속에 대한 설정값들을 가지고 있을 것이다
접속할 DB에 대한 설정은 JDBC가 해당 DB에 접근하기 위해 필수적이므로 무조건 입력해줘야 하는 설정값들이다.
먼저 DB 방언(DB Dialect)에 대해 알아볼 필요가 있다.
JPA의 가장 큰 특징은 특정 DB에 종속적이지 않다는 것이다. 따라서 JPA를 활용하기 위해서는 SQL 표준을 따라 코드를 짤 필요가 있다.
하지만 여러 가지 DB가 존재하는 만큼 DB마다 차이점이 존재한다. 데이터 타입이 다를 수도 있고, 함수명이 다를 수도 있으며, Paging 처리 방법도 다를 수 있다. 이런 SQL 표준을 지키지 않거나 특정 DB에만 존재하는 고유한 기능을 JPA에서는 DB 방언(Dialect)라고 한다.
우리는 결국 특정 DBMS를 활용하기 때문에 접속할 DB에 대한 속성 이외에도 활용할 DBMS를 Dialect로써 등록시켜줘야 해당 DBMS 기능을 100% 활용할 수 있게 되는 것이다.
(하지만 굳이 방언을 설정하지 않아도 JPA 활용은 가능하다)
DB 방언 설정 방법은 아래와 같다
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect" />
필수 사항은 아니기 때문에 굳이 입력하지 않아도 된다.
value는 "true", "false"로 지정하며 "true"일 경우 해당 기능을 활용한다는 의미를 가진다.
Schema 자동 생성 옵션이란 만약 모든 Entity에 대한 설정이 완료된 이후 애플리케이션을 실행시킬 때 로직을 실행시킬 Table의 구조(Schema)를 어떤 방식으로 자동 생성시킬 것인지에 대한 설정 방법이다.
예를 들어 Table A와 Table B가 Super-Sub Type이여야 한다면 JPA는 애플리케이션이 구동할 때 이를 이해하여 자동으로 Table A와 Table B를 형성하고 연관관계까지 구축해주는 것이다.
설정 방법 및 Value는 아래와 같다.
<property name="hibernate.hbm2ddl.auto" value="create" />
먼저 이 기능은 개발 환경에서나 활용하지 운영 환경에서는 활용하지 않는 것을 추천한다.
JPA는 Entity 관계 설정이 일치하기만 한다면 대충 Table을 만들어 버리기 때문에 Schema 자동 생성 기능이 만든 DDL 성능이 그렇게 좋지는 않다. 따라서 운영 환경에서 활용할 경우 매우 낮은 성능을 보이게 된다.
개발 시에는 create를 활용해도 되지만, 운영 시에는 validate나 Schema 자동 생성 기능을 꺼 놓는 것을 추천한다.(property 추가를 안 하면 됨)
Update는 뭔가 좋아보이겠지만 여러 명의 개발자들이 작업을 하는 환경에서는 Schema가 꼬여 심각한 경우 에러 발생 해결을 위해 Table을 갈아엎는 상황이 발생할 수 있으므로 Update는 아예 사용하지 않는 것을 추천한다.
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
만약 Entity Class의 멤버 변수와 어떤 Column이 매핑되는지 명시하지 않을 경우 JPA에서 정해진 Naming Rule에 따라 Mapping 관계를 설정한다.
예를 들자면 Camel Case 방식으로 Column Name과 멤버 변수를 매핑시킬 수도 있을 것이고, Snake Case 방식을 활용할 수도 있을 것이다.
이런 자동 Mapping 시 Naming Rule을 지정해주는 설정이 바로 "hibernate.ejb.naming_strategy"이다.
하지만 개인적으로 Naming Rule을 활용하는 것은 Table에 의존적인 개발이 된다고 생각하여 사용을 권장하는 Property는 아니다.
설명했던 persistence.xml은 Spring Boot, 정확히는 Spring Data JPA를 활용하지 않을 떄 설정 방식이다.
하지만 Spring Data JPA를 활용할 경우 application.properties에 설정값을 넣어주면 Spring Data JPA가 알아서 persistence.xml 파일 형식에 맞게 변환시킨 이후 EntityManagerFactory를 만들어 애플리케이션 전역에서 활용할 수 있게 만들어주므로 중간 과정 로직에 대한 고민 없이 개발을 진행할 수 있다.
물론 persistence.xml도 배워두면 좋은 지식이 되기는 하지만 최종적으로 우리는 Spring Data JPA를 사용해 JPA를 활용할 것이므로 application.properties 설정 방법에 대해서도 잘 알아두자
# 사용할 DB Settings
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jpadb
spring.datasource.username=root
spring.datasource.password=root
# JPA 옵션 Setting
spring.jpa.hibernate.ddl-auto=none # create, create-drop, validate, update, none
spring.jpa.gernerate-ddl=false
spring.jpa.show-sql=true
spring.jpa.database=mysql
spring.jpa.database-platform=org.hibernatedialect.MySQL5InnoDBDialect
spring.jpa.properties.hibernate.format_sql=true
# hibernate Logging
logging.level.org.hibenrate=info
사용할 DB Settting 같은 경우 항상 동일하기 때문에 따로 설명하지 않겠다
Hibernate의 Logging Level을 설정하는 것으로써 info, debug, warn, error, fatal이 존재한다.
주로 info로 많이 설정해 놓으며 info 보다 더욱 자세히 보고 싶다면 debug로 값을 바꾸면 된다.
(로그 레벨의 위급 정도는 debug < info < warn < error < fatal 순으로 설정 되어 있기 때문에 debug로 설정할 경우 사실상 발생하는 모든 이벤트를 로깅할 것이다)
persistence.xml에서 추가 설정 옵션에 해당하는 부분이다.
persistence.xml과 마찬가지로 입력해도 되고 안해도 되는 옵션에 대한 설정 부분이다.