스프링 부트 스타터(https://start.spring.io/)
Project: Gradle - Groovy Project
사용 기능: web, thymeleaf, jpa, h2, lombok, validation
groupId: jpabook
artifactId: jpashop
Project : Gradle-groovy
Language : Java
Spring Boot : 3.0.6
라이브러리
Lombok : 지루하게 반복하는 코드를 지워줌
package jpabook.jpashop;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class JpashopApplication {
// 메인 메서드까지 들어있음
public static void main(String[] args) {
SpringApplication.run(JpashopApplication.class, args);
}
}
실행하면 내장 톰켓 서버 8080포트로 들어갈 수 있음
라이브러리가 왜 이렇게 많지?
build.gradle에서
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 하나만 땡겨도
gradle은 기본적으로 의존 관계가 필요한 애들을 쭉쭉쭉 다 땡겨서 많아지는 거임
file -> setting -> plugins -> Lombok
Preferences Annotation Processors 검색 Enable annotation processing 체크 (재시작)
원래는 Gettet, Setter를 다만들었지만 Lombok를 이용하면 자동으로 추가해준다.
Hello class
package jpabook.jpashop;
import lombok.Getter;
import lombok.Setter;
@Getter @Setter
public class Hello {
private String data;
}
// main 안에 hello 객체를 만들고 Getter, Setter가 잘 생성되었는지 확인
@SpringBootApplication
public class JpashopApplication {
public static void main(String[] args) {SpringApplication.run(JpashopApplication.class, args);
Hello hello = new Hello(); // hello 객체 생성
hello.setData("hello");
String data = hello.getData();
System.out.println("data = " + data);
}
}
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
이걸 쓰면 jpa, hirenate 등 spring과 관련된 걸 가져다가 씀
제일 중요한 jpa를 보면 aop와 관련된 것들, jdbc(com.zaxxer:HikariCP:5.0.1 히카리피시라고 커넥션 풀이다 Springboot 2.0부턴 기본이다.) 등등 있어요
Spring-boot-starter를 쓰면 대부분 logging을 의존하고 있다.
ch.qos.logback:logback-classic:1.4.7 logback을 쓰는게 대세
핵심 라이브러리
스프링 MVC
스프링 ORM
JPA, 하이버네이트
스프링 데이터 JPA
기타 라이브러리
H2 데이터베이스 클라이언트
커넥션 풀: 부트 기본은 HikariCP
WEB(thymeleaf)
로깅 SLF4J & LogBack
테스트
스프링 데이터 JPA는 스프링과 JPA를 먼저 이해하고 사용해야 하는 응용기술이다
View 환경 설정
thymeleaf.org : thymeleaf 공식 사이트
장점 : html 마크업을 깨지 않고 그대로 쓴다, 웹 브라우저에서 열림
스프링 공식 튜토리얼: https://spring.io/guides/gs/serving-web-content/
스프링부트 메뉴얼: https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/
boot-features-developing-web-applications.html#boot-features-spring-mvc-templateengines
jpabook.jpashop.HelloController
package jpabook.jpashop;
import org.springframework.ui.Model;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller // 스프링에서 컨트롤러를 담당하는 클래스가 됨
public class HelloController {
@GetMapping("hello") // hello라는 url에 매핑이 되면
// Spring ui에 있는 Model이라는 애가 model에다가 data를 실어서 컨트롤러에 의해 view에 넘길 수 있다.
public String hello(Model model){
model.addAttribute("data", "hello!!!");
return "hello"; // return은 화면 이름 resources에 templates의 hello.html로 감
}
}
thymeleaf 템플릿엔진 동작 확인(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>
위치: resources/templates/hello.html
hello 라는 이름만 적었는데 어떻게 resources 폴더에 templates 폴더에 hello.html 파일을 찾을까? -> Springboot가 해주는거임
static/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>
정적 컨텐츠는 static에 동적 컨텐츠는 templates에 하면 됨
spring-boot-devtools 라이브러리를 추가하면, html 파일을 컴파일만 해주면 서버 재시작 없이
View 파일 변경이 가능하다.
인텔리J 컴파일 방법: 메뉴 build Recompile
개발이나 테스트 용도로 가볍고 편리한 DB, 웹 화면 제공
버전 2.1.214
https://www.h2database.com
다운로드 및 설치
데이터베이스 파일 생성 방법
jdbc:h2:~/jpashop (최소 한번)
~/jpashop.mv.db 파일 생성 확인
이후 부터는 jdbc:h2:tcp://localhost/~/jpashop 이렇게 접속
main/resources/application.yml
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/jpashop;MVCC=TRUE
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate: create # create: 자동으로 테이블을 만들어주는 모드
proterties:
hibernate:
# show_sql: true # System.out으로 찍고
format_sql: true
logging:
level:
org.hibernate.SQL: debug #logging으로 찍고
spring.jpa.hibernate.ddl-auto: create
이 옵션은 애플리케이션 실행 시점에 테이블을 drop 하고, 다시 생성한다.
모든 로그 출력은 가급적 로거를 통해 남겨야 한다.
show_sql : 옵션은 System.out 에 하이버네이트 실행 SQL을 남긴다.
org.hibernate.SQL : 옵션은 logger를 통해 하이버네이트 실행 SQL을 남긴다.
@Entity // DB테이블에 대응하는 하나의 클래스, JPA가 관리 JPA를 사용해 DB 테이블과 매핑할 클래스에 붙여줌
@Getter @Setter // getter, setter 자동 생성
public class Member {
@Id @GeneratedValue // @Id: 기본키 설정 @GeneratedValue: 기본키 생성 전략
private long id;
private String username;
}
package jpabook.jpashop;
// Repository가 Entity같은 거를 찾아주는 애
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
@Repository //@Component 스캔에 대상이되어 자동으로 스프링 빈에 등록이됨
public class MemberRepository {
@PersistenceContext // JPA의 EntityManager를 주입받는 어노테이션 EntityManager는 JPA에서 DB의 작업을 담당하는 주요 객체
private EntityManager em;
public Long save(Member member){ // 저장
em.persist(member);
return member.getId(); // member만 반환하지 않고 getId까지 반환하는 이유 : 커맨드와 쿼리를 분리해라
}
public Member find(Long id){ // 조회
return em.find(Member.class, id);
}
}
package jpabook.jpashop;
import jakarta.transaction.Transactional;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@Test
@Transactional //@Transactional이 test에 있으면 실행이 끝나고 db를 롤백해버림
@Rollback(false) // 롤백을 하지않고 커밋해버림
public void testMember() throws Exception{
// given
Member member = new Member();
member.setUsername("memberA");
// when
Long saveId = memberRepository.save(member);
Member findMember = memberRepository.find(saveId);
// then
Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
Assertions.assertThat(findMember).isEqualTo(member); //JPA 엔티티 동일성보장 true가 나와야 함
}
}
application.yml의 logging에 org.hibernate.orm.jdbc.bind: trace 추가하면
1번 파라미터는 VARCHAR 2번 파라미턴S BIGINT라는 로고를 찍어준다.
?값도 궁굼해짐
build.gradle에
implementation 'org.springframework.boot:spring-boot-starter-validation'
라이브러리를 추가해주면됨