Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 스프링 mvc1 - 스프링 mvc
- 스프링 mvc1 - 서블릿
- 자바의 정석 기초편 ch1
- 스프링 db1 - 스프링과 문제 해결
- 게시글 목록 api
- 자바의 정석 기초편 ch12
- 자바의 정석 기초편 ch3
- 스프링 mvc2 - 로그인 처리
- 스프링 mvc2 - 타임리프
- 자바 기본편 - 다형성
- 코드로 시작하는 자바 첫걸음
- 자바의 정석 기초편 ch14
- 자바의 정석 기초편 ch6
- 스프링 db2 - 데이터 접근 기술
- @Aspect
- jpa - 객체지향 쿼리 언어
- 2024 정보처리기사 시나공 필기
- 자바의 정석 기초편 ch13
- 스프링 고급 - 스프링 aop
- jpa 활용2 - api 개발 고급
- 자바의 정석 기초편 ch8
- 자바의 정석 기초편 ch11
- 자바의 정석 기초편 ch7
- 자바의 정석 기초편 ch4
- 스프링 입문(무료)
- 자바의 정석 기초편 ch5
- 2024 정보처리기사 수제비 실기
- 스프링 mvc2 - 검증
- 자바의 정석 기초편 ch2
- 자바의 정석 기초편 ch9
Archives
- Today
- Total
나구리의 개발공부기록
프로젝트 환경설정, 프로젝트 생성, 라이브러리 살펴보기, View 환경 설정, H2 데이터베이스 설치, JPA와 DB설정, 동작확인 본문
인프런 - 스프링부트와 JPA실무 로드맵/실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
프로젝트 환경설정, 프로젝트 생성, 라이브러리 살펴보기, View 환경 설정, H2 데이터베이스 설치, JPA와 DB설정, 동작확인
소소한나구리 2024. 9. 26. 17:02출처 : 인프런 - 실전! 스프링 부트와 JPA활용1 - 웹 애플리케이션 개발(유료) / 김영한님
유료 강의이므로 정리에 초점을 두고 코드는 일부만 인용
1. 프로젝트 생성
(1) Project Setting
- Gradle - Groovy
- Java 17
- Jar
- Spring Boot3.3.4
- group: jpabook
- Artifact: jpashop
(2) Dependencies
- Spring Data JPA
- Spring Web
- Thymeleaf
- Validation - 스프링 부트 3.x.x 버전부터는 직접 추가해야함
- Lombok
- B2 Database
(3) build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.4'
id 'io.spring.dependency-management' version '1.1.6'
}
group = 'jpabook'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
(4) 롬복 - Hello 클래스 생성
- 플러그인에서 Lombok 설치 확인
- 인텔리제이 setting -> annotaion processors 검색 -> Enabld annotation processing 활성화(인텔리제이 버전이 2021년 이상 버전에서는 해당 설정을 하지 않아도 잘 동작함, 만약 동작하지 않는다면 해당 설정을 진행)
- @Getter, @Setter 애노테이션으로 게터, 세터를 자동으로 만들어주고, 이 외에도 기본생성자, 생성자 등등 여러가지 기능을 애노테이션으로 편리하게 설정하는 기능을 제공함 - 롬복의 기능은 스프링 강의에 자세히 나와있음
@Getter
@Setter
public class Hello {
private String data;
}
2. 라이브러리 살펴보기
1) 스프링부트 라이브러리 살펴보기
(1) spring-boot-starter-web
- spring-boot-starter-tomcat: 톰캣(웹서버)
- spring-webmvc: 스프링 웹MVC
- spring-boot-starter
- spring-boot
- spring-core
- spring-boot-starter-logging
- logback, slf4j
- spring-boot
(2) spring-boot-starter-thymeleaf: 타임리프 템플릿 엔진(View)
(3) spring-boot-stater-data-jpa
- spring-boot-starter-aop
- spring-boot-stater-jdbc
- HikariCP 커넥션 풀(부트 2.0부터 기본)
- hibernat-core: 하이버네이트 + JPA
- spring-data-jpa: 스프링 데이터 JPA
2) 테스트 라이브러리
- spring-boot-stater-test
- junit: 테스트 프레임워크
- mockito: 목 라이브러리
- assertj: 테스트 코드를 좀 더 편하게 작성하게 도와주는 라이브러리
- spring-test: 스프링 통합 테스트 지원
3) 핵심 라이브러리
- 스프링 MVC
- 스프링 ORM
- JPA, 하이버네이트
- 스프링 데이터 JPA: JPA를 먼저 이해하고 사용해야하는 응용 기술
4) 기타 라이브러리
- H2 데이터베이스 클라이언트
- 커넥션 풀: HikariCP(스프링 부트 기본)
- WEB(thymeleaf)
- 로깅: SFL4J & LogBack
- 테스트
3. View 환경 설정
- thymeleaf 공식 사이트
- 스프링 공식 튜토리얼
- 스프링부트 메뉴얼
- 스프링 부트 thymeleaf viewName 매핑
- resources:templates/ + {ViewName} + .html
- 스프링은 thymeleaf를 밀고있으며 타임리프 3.0 되면서 성능개선, 편리성이 많이 올라오게 되었음
- 단점은 메뉴얼을 보면서 좀 익혀야하지만 익히게 되면 되게 편리함
1) HelloController
@Controller
public class HelloController {
@GetMapping("hello")
public String hello(Model model) {
model.addAttribute("data", "hello~!~!~!~!~!~!~!~!~!~!");
return "hello";
}
}
2) thymeleaf 템플릿엔진 동작 확인
(1) resources/templates/hello.html - 동적 템플릿
- 서버를 실행하고 localhost:8080에 접속하면 HelloController에서 넘긴 값이 ${data}에 치환되어서 입력된 것을 확인할 수 있음
- 그냥 로컬에서 hello.html을 열면 natural template으로 동작하여 기본값으로 입력해둔 안녕하세요. 손님 이라는 문구가 출력됨 - thymeleaf의 장점(마크업을 깨지 않고 파일 자체를 웹브라우저로 열어서 확인해볼 수 있음)
<!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 라이브러리를 추가하면 html 파일을 컬파일만 해주면 서버 재시작 없이 View 파일 변경이 가능함
- 인텔리제이 컴파일 방법: build -> Recomple
implementation 'org.springframework.boot:spring-boot-devtools'
(2) resources/static/index.html - 웰컴페이지(정적인 순수 html)
- 서버 실행후 localhost:8080으로 접속하면 바로 처음에 나오는 정적 페이지를 생성
<!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>
4. H2 데이터베이스 설치
1) 다운로드 및 설치
- https://www.h2database.com
- 사이트 접속 후 스프링 부트 버전에 맞게 설치 - 스프링 부트 3.x면 2.1.214버전 이상을 사용
2) 데이터베이스 파일 생성 방법
- 설치 후 h2데이터베이스 폴더의 bin에 있는 h2.sh파일을 실행
- JDBC URL: jdbc:h2:~/jpashop 설정 후 연결 (최소 한번)
- home 경로에 jpashop.mb.db 파일이 생성되었는지 확인
- 이후 부터는 jdbc:h2:tcp://localhost/~/jpashop 으로 접속
5. JPA와 DB설정, 동작확인
1) main/resources/application.yml
- application.properties가 아닌 application.yml을 만들어서 설정을 적용
- 들여쓰기로 구분되어 가독성이 좋아서 설정이 복잡할때 사용하면 좋음
- 단, 들여쓰기 구분이 틀리면 설정 적용이 안되므로 들여쓰기에 주의해야함
- 설정 정보는 Spring.doc의 Srping Boot공식 메뉴얼에서 공부를 해야함
# yml은 띄어쓰기에 주의해야함
spring: # 띄어쓰기 없음
datasource: # 띄어쓰기 2칸
url: jdbc:h2:tcp://localhost/~/jpashop # 띄어쓰기 4칸
username: sa
password:
driver-class-name: org.h2.Driver
jpa: # 띄어쓰기 2칸
hibernate: # 띄어쓰기 4칸
ddl-auto: create # 띄어쓰기 6칸
properties:
hibernate:
# show_sql: true # 띄어쓰기 8칸, System.out으로 출력 -> 실무에서는 사용안함
format_sql: true # Log로 출력
logging: # 띄어쓰기 없음
level: # 띄어쓰기 2칸
org.hibernate.SQL: debug # 띄어쓰기 4칸 -> JPA 쿼리 출력
# org.hibernate.orm.jdbc.bind: trace # SQL에서 파라미터값이 ?로 나오는데 그것을 실제 값으로 출력
2) 실제 동작 확인
(1) 회원 엔터티
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
}
(2) 회원 리포지토리
- 회원 저장 시 Member를 반환해도 되지만 커맨드(명령)과 쿼리(조회)를 분리하라는 원칙을 적용하여 유지보수성과 시스템 안정성을 높이는 설계를 적용
- save() 메서드는 member 객체를 데이터베이스에 저장하는 역할을 하고 이 과정에서 상태 변경이 일어나는 명령 메서드이기 때문에 그결과로 상태를 반환하기 보다 식별자만 반환하도록 설계하여 데이터 저장에 집중하고 조회기능을 따로 분리함
- find() 메서드로 save()에서 반환된 id값을 가지고 조회 기능만 하는 메서드를 생성해서 조회는 find()메서드를 통해서만 할 수 있도록하여 save()를 통해 객체를 조회 없이 조작할 수 있는 상황을 방지
- 이렇게 각 메서드가 정해진 기능에 맞게 집중해서 사용하도록 설계되어있으면 데이터 무결성을 잘 보장할 수 있음
package jpabook.jpashop;
@Repository
public class MemberRepository {
@PersistenceContext // 생략 가능
private EntityManager em;
public Long save(Member member) {
em.persist(member); // 저장
// 커맨드와 쿼리를 분리하라는 원칙에 의해 member를 반환하는게 아닌, member.id()만 반환해서 리턴값으로 조회할 수 있도록 설계
return member.getId();
}
public Member find(Long id) {
return em.find(Member.class, id);
}
}
(3) MemberRepositoryTest
- Junit5를 사용한 테스트, Junit4를 사용했다면@ExtgendWith(SpringExtension.class)를 @Runwith(SpringRunner.class)로 입력해야함
- 스프링 부트 2.1 이상 버전을 사용해서 빌드를 했다면 @SpringBootTest 만으로도 자동으로 SpringExtension을 추가해주기 때문에 생략해도 됨
- 마지막 테스트가 성공하는 이유는 JPA의 영속성 컨텍스트와 1차 캐시 메커니즘 때문인데, 영속성 컨텍스트는 동일성을 보장하며 같은 영속성 컨텍스트 내에서 같은 ID를가진 엔터티는 동일한 인스턴스가 됨 -JPA 기본편에서 자세히 배움
package jpabook.jpashop;
@ExtendWith(SpringExtension.class)
@SpringBootTest
class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@Test
@Transactional // 테스트에서 적용시 테스트가 끝나면 자동으로 롤백
// @Rollback(false) // 롤백을 false로 설정하면 DB에 데이터가 저장됨
public void testMember() {
// given
Member member = new Member();
member.setUsername("memberA");
// when
Long savedId = memberRepository.save(member);
Member findMember = memberRepository.find(savedId);
// then
Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
Assertions.assertThat(findMember).isEqualTo(member);
}
}
(4) jar 빌드해서 동작 확인
- 터미널에서 ~jpashop 위치로 이동 후 ./gradle clean build를 실행
- ~/jpashop/build/libs에 생성된 jpashop-0.0.1-SNAPSHOT.jar를 실행하여 배포 실행
- 실행 후 localhost:8080으로 접속하면 정상적으로 웹이 띄워지고 실행이 잘 됨
- 실행 전 애플리케이션이 실행되고 있다면 (8080서버가 띄워져있다면) 끄고 다시 실행해야함
java -jar jpashop-0.0.1-SNAPSHOT.jar
** 참고
- 스프링 부트를 통해 복잡한 설정이 다 자동화 되어서 persistence.xml도 없고 LocalContainerEntityManagerFactoryBean도 없음