프로젝트 환경설정

박민서·2023년 5월 5일
0

Jpa1

목록 보기
1/6

프로젝트 생성

스프링 부트 스타터(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은 기본적으로 의존 관계가 필요한 애들을 쭉쭉쭉 다 땡겨서 많아지는 거임

  • Lombok 적용
  1. file -> setting -> plugins -> Lombok

  2. Preferences Annotation Processors 검색 Enable annotation processing 체크 (재시작)

  • Lombok 확인

원래는 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과 관련된 걸 가져다가 씀

  • 의존관계(Dependecies) 확인

    spring-boot-starter-web이 내장 톰켓 서버도 땡겨와서 8080서버를 쓸 수 있다
    spring-boot-starter-web이 org.springframework:spring-webmvc:6.0.8e을 의존하고 있는 것도 중요하다.


제일 중요한 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를 먼저 이해하고 사용해야 하는 응용기술이다

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가 해주는거임

  • 랜더링을 하지 않고 순수한 html을 뿌리고 싶으면 resources 폴더에 static 폴더에 html파일을 만들면된다.

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

H2 데이터베이스 설치

개발이나 테스트 용도로 가볍고 편리한 DB, 웹 화면 제공
버전 2.1.214
https://www.h2database.com
다운로드 및 설치
데이터베이스 파일 생성 방법
jdbc:h2:~/jpashop (최소 한번)
~/jpashop.mv.db 파일 생성 확인
이후 부터는 jdbc:h2:tcp://localhost/~/jpashop 이렇게 접속

JPA와 DB 설정, 동작확인

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;
}
  • 회원 리포지토리
    Member Repository
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);
    }

}
  • 테스트
    MemberRepositoryTest
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가 나와야 함
    }
}
  • 어마어마한 꿀팁
    JPA를 쓰면 좀 답답한게 SQL 나가는거랑 DB커넥션 가져오는게 도대체 어느 타이밍에 일어나는지 궁굼할때가 많음

application.yml의 logging에 org.hibernate.orm.jdbc.bind: trace 추가하면

1번 파라미터는 VARCHAR 2번 파라미턴S BIGINT라는 로고를 찍어준다.


?값도 궁굼해짐
build.gradle에

implementation 'org.springframework.boot:spring-boot-starter-validation'

라이브러리를 추가해주면됨

출처 :https://www.inflearn.com/course/lecture?courseSlug=%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1&unitId=24281

profile
ㅎㅇㅌ

0개의 댓글