프로젝트 구성 - jpa 적용

born_a·2022년 9월 14일
0

엔티티

Hello.java

@Getter
@Setter
public class Hello {
    private String data;
}

Member.java

@Entity
@Getter
@Setter
public class Member {

    @Id @GeneratedValue
    private Long id;

    private String username;

}

컨트롤러

HelloController

@Controller
public class HelloController {

    @GetMapping("hello")
    public String hello(Model model) { //컨트롤러에서 model에 데이터를 싫어서 뷰로 넘긴다.
        model.addAttribute("data", "hello!!");
        return "hello"; //return은 화면이름 . hello에 자동으로 .html이 붙는다
    }
}

리포지토리

MemberRepository.java

@Repository //컴포넌트 스캔이 되는 어노테이션 중 하나. 자동으로 스프링 빈에 등록됨
public class MemberRepository {
    //jpa를 쓰기 때문에 entity manager가 있어야한다.
    @PersistenceContext //이 애노테이션이 있으면 스프링부트가 entity manager를 주입해준다
    private EntityManager em;

    public Long save(Member member) {
        em.persist(member);
        return member.getId(); //저장을 하면 리턴값을 Id 정도만
    }

    public Member find(Long id) {
        return em.find(Member.class, id);
    }

}

resource 폴더

static

렌더링 안하고 페이지 그냥 띄우고 싶을 때 : static 폴더에!

templates

템플릿 가지고 렌더링 넣어야 할 때 : templates 폴더에!

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>

application.yml

spring:
  datasource:
    url: jdbc:h2:tcp://localhost/~/jpashopapply
    username: sa
    password:
    driver-class-name: org.h2.Driver

  jpa:
    hibernate:
      ddl-auto : create #애플리케이션 실행시점에 다 지우고 다시 생성
    properties:
      hibernate:
#        show_sql: true //얘는 system.out에 출력을 하는거. 실무에선 쓰면 된다.
        format_sql : true

logging:
  level:
    org.hibernate.SQL: debug #얘는 로그에 출력함

devtools

build.gradle 에 추가

compileOnly 'org.springframework.boot:spring-boot-devtools'

h2 db 연결 에러

터미널에서 sudo lsof -i:"포트번호"
에서 8082 사용하는 pid를 찾는다.
그 후, kill -9 "pid번호" 로 해당 pid를 없앤다.
다시 ./h2.sh를 해주어 h2 콘솔을 띄운다.

MemberRepositoryTest.java

@RunWith(SpringRunner.class) //junit한테 나 스프링 관련해서 테스트 할거야 라고 알려줌
@SpringBootTest
public class MemberRepositoryTest {
    @Autowired
    MemberRepository memberRepository;

    @Test
    @Transactional //entity manager관한 모든건 트랜잭션 안에서 이루어지므로 추가해야한다
    @Rollback(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
        Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
        Assertions.assertThat(findMember).isEqualTo(member);
        System.out.println("findMember == member : " + (findMember == member));
    }
}

테이블에 데이터가 없는 이유

@Transactional 어노테이션이 테스트 케이스에 있으면 테스트가 끝나고 db를 롤백을 해버린다.

@Rollback(false)를 추가하면 데이터가 들어와있는것을 확인 가능.
롤백안하고 커밋한 것.

저장한 member와 조회한 findMembers는 같을까?

같은 트랜잭션 안에서 저장하고 조회하면 영속성 컨텍스트가 똑같겠지? 같은 영속성 컨텍스트 안에서는 id같이 같으면 같은 엔티티로 식별한다.

쿼리 파라미터 로그 남기기

org.hibernate.type:trace 추가

외부 라이브러리 사용

build.gradle에 추가
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'


처음에는 원본이 출력되고, 파라미터 바인딩 된 정보가 함께 출력된다.

성능 저하를 일으킬 수 있기 때문에, 운영시스템에서는 성능테스트 후에 적용해야한다.

0개의 댓글

관련 채용 정보