앞서 DB를 설치했으니, 이제는 이 DB를 사용하는 프로젝트를 생성할 것이다.
참고로 자바 ORM 표준 JPA 프로그래밍
교재와는 조금 다르게 한다.
아무튼 intellij 를 통한 프로젝트 생성법을 알아보자.
maven 프로젝트 생성한다.
그리고 archetype은 maven-archetype-quickstart
를 선택한다.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>hello</groupId>
<artifactId>jpa_basic</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- JPA 하이버네이트 -->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.6.3.Final</version>
</dependency>
<!-- H2 데이터베이스 -->
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version> <!-- 이거는 자신이 다운로드한 h2 버전에 맞게 수정 -->
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.21.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
</project>
참고로 나는 H2 버전이 1.4.200
이다.
자신의 버전이 뭔지 모르겠으면 H2 Console
에서SELECT H2VERSION() FROM DUAL
을
통해서 알아내면 된다.
그리고 lombok 을 적용하려면 intellij 에서는 조금 더 작업할 것이 있다.
일단 lombok 플러그인이 없다면 설치하고 나서 아래 사진처럼 File > Settings
에 들어가서 annotation processor
를 enable 시켜줘야 한다.
1. src/main/resources/META-INF/persistence.xml
파일 생성
2. 아래 내용을 복붙
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<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="sa"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/goodjob"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.physical_naming_strategy" value="org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy"/>
<!-- 옵션 -->
<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.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
persistence-unit
: JPA 설정의 시작이며, 일반적으로 연결할 DB당 하나씩 생성hibernate.dialect
: 방언 선택hibernate.show_sql
: 하이버네이트가 실행한 SQL을 출력hibernate.format_sql
: 하이버네이트가 실행한 SQL을 정렬하여 출력hibernate.use_sql_comments
: 쿼리를 출력할 때 주석도 함께 출력hibernate.hbm2ddl.auto
:create
: 스키마 삭제하고 새로 생성create-drop
: 삭제 ->
생성 ->
삭제update
: 변경된 스키마만 update, 그외 기존의 것들 유지validate
: 객체와 스키마의 매핑 유효성 체크none
: 아무것도 안함<property name="hibernate.physical_naming_strategy" value="org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy"/>
는 Java 클래스에서는 CamelCase, Table 에서는 Snake Case를 사용하도록 설정하는 것이다.
3. intellij 가 제공하는 JPA Facet 설정을 할 것인지 물어보는 알림이 뜨면 클릭해준다.
필요한 로그만 뽑아서 찍도록 작성한다.
참고로 생성 위치는 src/main/resources/logback.xml
이다.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta(%-4relative) --- [ %thread{10} ]
%cyan(%logger{20}) : %msg%n
</pattern>
</encoder>
</appender>
<logger name="org.hibernate.SQL" level="info"/>
<root level="warn">
<appender-ref ref="CONSOLE"/> <!-- Console에 로그를 출력하고자 할 때 사용 -->
</root>
</configuration>
package hello.basic;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class JpaBasicTest {
// 모든 테스트에선 Factory 를 공유해서 사용한다.
static EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
@Test
void testEntitySelect() {
defaultTestTemplate((entityManager) -> {
// 앞으로 여기에만 핵심 로직을 작성하면 된다.
});
}
// 모든 @Test 에서 아래 같은 흐름으로 코드가 진행된다.
// 반복되는 코드를 없애기 위해서 콜백(testCallback)을 사용해서
// 각 @Test 메소드에서는 핵심 로직만 작성하도록 한다.
private void defaultTestTemplate(Consumer<EntityManager> testCallback) {
final EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
// 테스트 소스 작성
testCallback.accept(em);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
em.close();
}
}
@AfterAll
static void AfterAll() {
emf.close();
}
}
앞으로 이렇게 Junit5 를 통해서 테스트를 진행할 것이다.
이렇게 장황하게 미리 준비하는게 귀찮으면 JPA 이론서와 똑같이 main 메소드에서 실습해도 된다.
https://stackoverflow.com/questions/32165694/spring-hibernate-5-naming-strategy-configuration
https://velog.io/@mumuni/Hibernate5-Naming-Strategy-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC
CamelCaseToUnderscoresNamingStrategy 관련:
https://in.relation.to/2021/07/19/hibernate-orm-554-release/