프로젝트 생성
- Spring Initializr에서 프로젝트 생성
- 프로젝트 구성
- Gradle Project, Java Language
- Spring 2.4.X version, Java 11 version
- Group Id : jpabook, Artifact Id : jpashop - 의존성 구성
- Spring Web Starter
- Thymeleaf
- Spring Data JPA
- H2 Database
- Lombok
- Validation
JUnit 4 설정
해당 강의는 JUnit4를 기준으로 진행하기 때문에 build.gradle
내에 아래 구문을 추가해야 한다. 추가하지 않을 경우 JUnit5로 동작한다.
// JUnit4 추가
testImplementation("org.junit.vintage:junit-vintage-engine") {
exclude group: "org.hamcrest", module: "hamcrest-core"
}
프로젝트 동작 확인
Main 클래스 실행
프로젝트가 정상적으로 생성, import 되었는지 JpashopApplication
클래스를 실행시켜본다.
동작 결과
Test Main 클래스 동작 확인
기본 테스트가 정상 동작 하는지 확인해본다.
동작 결과
Lombok 동작 확인
Lombok이란 어노테이션을 기반으로 코드를 자동완성 해주는 라이브러리로 Getter, Setter, ToString, Equals 등 다양한 코드를 자동완성 해준다.
예제
- Hello.java
import lombok.Getter;
import lombok.Setter;
@Getter @Setter
public class Hello {
private String name;
}
- JpashopApplication.java
@SpringBootApplication
public class JpashopApplication {
public static void main(String[] args) {
// Lombok 테스트
Hello hello = new Hello();
hello.setName("hello");
System.out.println("hello : " + hello.getName());
SpringApplication.run(JpashopApplication.class, args);
}
}
동작 결과
라이브러리 살펴보기
스프링 부트 라이브러리
- spring-boot-starter-web
ㄴ spring-boot-starter-tomcat : 톰캣(웹 서버)
ㄴ spring-webmvc : 스프링 웹 MVC - spring-boot-starter-thymeleaf : 타임리프 템플릿 엔진(view)
- spring-boot-starter-data-jpa
ㄴ spring-boot-starter-aop
ㄴ spring-boot-starter-jdbc
ㄴ HikariCP 커넥션 풀 (스프링 부트 2.0 기본 포함)
ㄴ hibernate + JPA : 하이버네이트 + JPA
ㄴ spring-data-jpa : 스프링 데이터 JPA - spring-boot-starter : 스프링 부트 + 스프링 코어 + 로깅
ㄴ spring-boot
ㄴ spring-core
ㄴ spring-boot-starter-logging
ㄴ logback, slf4j
테스트 라이브러리
- spring-boot-starter-test
ㄴ junit : 테스트 프레임워크
ㄴ mockito : 목 라이브러리
ㄴ assertj : 테스트 코드를 좀 더 편하게 작성하도록 도와주는 라이브러리
ㄴ spring-test : 스프링 통합 테스트 지원
핵심 라이브러리
- Spring MVC
- Spring ORM
- JPA, Hibernate
- Spring Data JPA
기타 라이브러리
- H2 Database
- Thymeleaf
- 로깅 slf4j(인터페이스) & logback(구현체)
- 테스트 관련
View 환경설정
Thymeleaf 템플릿 엔진 사용하여 View 구성한다.
정적파일 테스트
정적 페이지 및 파일은 resources/static
경로에 생성하여 사용한다.
예제
최초 진입시 출력되는 index.html
을 구성해보자
- index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
Hello
<a href="/hello">hello</a>
</body>
</html>
템플릿 엔진 동작 테스트
Thymeleaf의 View Name은 resources/templates
경로 내 파일명과 매핑된다.
예제
간단한 페이지를 구성하여 Thymeleaf 엔진 동작 테스트를 진행해보자.
- HelloController.java
@Controller
public class HelloController {
@GetMapping("hello")
public String hello(Model model) {
model.addAttribute("data", "hello!!");
return "hello"; // 화면명 리턴
}
}
- hello.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'안녕! ' + ${data}">안녕하세요. 손님</p>
</body>
</html>
동작 결과
Spring boot devtools
개발 편의를 위한 라이브러리로 주로 변경된 코드를 서버 또는 화면에 적용하는 동작을 한다.
- Property Defaults : 속성 옵션 기본값 설정 (캐싱 등)
- Automatic Restart : classpath 내 파일 변경 시 서버 재시작
- Live Reload : JSP, CSS 파일 변경 시 자동 새로고침
- Global Settings : 전역 프로퍼티 설정
- Remote Applications : 원격 개발지원
적용하기
- build.gradle
runtimeOnly 'org.springframework.boot:spring-boot-devtools'
동작 결과
H2 Database 설치
H2 데이터베이스는 가볍고 편리하며 웹 화면을 제공하기 때문에 개발이나 테스트 시 많이 사용한다. (해당 강의에서는 1.4.200 버전을 사용한다.)
실행하기
압축해제 후 h2-2019-10-14/h2/bin
경로에서 h2.bat
파일을 실행한다.
접속하기
접속 시 db파일을 생성시켜줘야 하는데 최초엔 jdbc:h2:~/jpashop
URL로 접속 후 이후부턴 네트워크 모드로 tcp를 이용해 jdbc:h2:tcp://localhost/~/jpashop
URL로 접속한다.
접속완료
JPA와 Database 설정 및 동작확인
YAML
YAML은 스프링부트의 설정파일 형식이다. 장점으로는 보기 쉬운 문법과 한 파일 내에서 profile로 다양한 설정을 관리할 수 있지만 단점으로는 띄어쓰기로 구분하기 때문에 주의해야 한다.
YAML 설정 적용하기
resources/
경로에 application.yml
파일을 생성하여 설정정보를 관리할 수 있다.
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/jpashop
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
# 애플리케이션 실행 시점에 DB 초기화 후 다시 DDL 실행
ddl-auto: create
properties:
hibernate:
# sysout으로 출력
# '[show_sql]': auto
'[format_sql]': true
logging:
level:
# JPA나 hibernate가 남기는 SQL이 다 logger로 출력
'[org.hibernate.SQL]': debug
YAML 설정 확인하기
애플리케이션 설정정보를 간단한 Member 정보를 찾는 테스트를 만들어 확인해보자
소스
- Member.java
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
}
- MemberRepository.java
@Repository
public class MemberRepository {
@PersistenceContext // 스프링부트가 알아서 EntityManager 생성
private EntityManager em;
/**
* Member save
* @param member
* @return member.id
*/
public Long save(Member member) {
em.persist(member);
return member.getId();
}
/**
* Member find
* @param id
* @return member
*/
public Member find(Long id) {
return em.find(Member.class, id);
}
}
- MemberRepositoryTest.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@Test
@Transactional // Test에서 사용 시 테스트 종료 후 롤백
@Rollback(value = false) // false 지정 시 롤백 안함
public void testMember() throws Exception {
// given
Member member = new Member();
member.setUsername("memberA");
// when
Long savedId = memberRepository.save(member);
Member findMember = memberRepository.find(savedId);
// then
// 엔티티 없어서 테스트 실패, 트랜잭션이 없기 때문
// @Transactional 어노테이션 추가하여 테스트 성공
Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
Assertions.assertThat(findMember).isEqualTo(member); // JPA 엔티티 동일성 보장
System.out.println("findMember == member : " + (findMember == member));
}
}
동작 결과
(1) @Transactional
추가 전 결과
(2) @Transactional
추가 후 결과
JAR 패키징 및 실행
jar 파일을 만들어서 빌드 및 실행을 할 수 있다.
JAR 패키징
JAR 파일 실행
쿼리 파라미터 로그 남기기
SQL에 들어가는 파라미터 로그를 설정 및 외부 라이브러리를 통해 남길 수 있다.
설정 변경
- application.yml
logging:
level:
'[org.hibernate.SQL]': debug
# SQL 파라미터 로그 출력
'[org.hibernate.type]': trace
외부 라이브러리
P6Spy 라이브러리를 통해 파라미터가 포함된 SQL 로그를 출력할 수 있다.
- build.gradle
// P6Spy 추가
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'
※ 참고로 SQL 파라미터를 로그로 남기는 외부 라이브러리는 시스템 자원을 사용하므로 개발 단계에서는 편하게 사용해도 되지만, 운영 시스템에 적용하려면 충분한 성능 테스트 후 적용해야 한다.
'Dev > JPA' 카테고리의 다른 글
[JPA] JPA 활용 I - 애플리케이션 구현 준비 (0) | 2021.09.16 |
---|---|
[JPA] JPA 활용 I - 도메인 분석 설계 (0) | 2021.09.15 |
[JPA] JPA 활용 I - 강좌 소개 (0) | 2021.09.14 |
[JPA] 객체지향 쿼리 문법 - 중급문법(2) (0) | 2021.09.11 |
[JPA] 객체지향 쿼리 언어 - 중급문법 (1) (0) | 2021.09.10 |
댓글