Appreance에서 gradle 설정 및 lombok설정
h2 db 실행은 여기를 참고
- chmod + x [프로그램명]
or
- chmod 755 h2.sh
https://animal-park.tistory.com/301
[Mac] zsh: permission denied: ./h2.sh
맥 터미널에서 프로그램 실행시 "zsh: permission denied: " 에러가 발생한 경우 해결하는 방법에 대해 알아보겠습니다. 해당 오류는 말그대로 파일실행 권한이 없어서 발생한 오류인데요. 해결방법은
animal-park.tistory.com
데이터베이스 파일 생성 방법
jdbc:h2:~/datajpa (최소 한번)
- jdbc:h2:~/datajpa
-
~/datajpa.mv.db 파일 생성 확인
이후 부터는 jdbc:h2:tcp://localhost/~/datajpa 이렇게 접속
스프링 데이터 JPA와 DB 설정, 동작확인
application.properties를 삭제하고 application.yml 파일을 생성
// application.yml
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/datajpa
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create // ddl-auto는 운영환경에서만 쓰고 개발환경에서는x
// 애플리케이션 로딩 시점에 테이블을 다 drop을 다 한 다음에 다시 깨끗하게 생성한다.
// 마지막에 애플리케이션 내려가도 테이블 남겨놓음 => db접근 결과확인
properties:
hibernate:
# show_sql: true // JPA가 실행하는 쿼리 콘솔에 찍음
format_sql: true
logging.level:
org.hibernate.SQL: debug // 로그파일로 남겨놓음
# org.hibernate.type: trace // 파라미터 바인딘됭 파라미터까지 볼 수 있는 옵션
entity - Member Class
package study.datajpa.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Getter @Setter
public class Member {
// 식별자를 알아서 매핑
@Id
// JPA가 알아서 순차적인 값 넣어줌
@GeneratedValue
private Long id;
private String username;
}
MemberRespository
package study.datajpa.repository;
import org.springframework.stereotype.Repository;
import study.datajpa.entity.Member;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Repository
public class MemberJpaRepository {
@PersistenceContext
// 엔티티 집어넣고 jpa가 db에다 insert query를 날려서 저장을 하게됨
private EntityManager em;
public Member save(Member member) {
em.persist(member);
return member;
}
public Member find(Long id) {
// jpa가 알아서 Member entity에 맞는 select query를 db에다가 가져오게 된다.
return em.find(Member.class, id);
}
}
test문 생성하고
Member Class를 아래와 같이 지정해준다.(@Setter 제거해도됨)
package study.datajpa.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Getter @Setter
public class Member {
@Id
@GeneratedValue
private Long id;
private String username;
// jpa가 proxy를 쓰고 구현체가 객체를 강제로 만들어 낼 때 열어 놓아야 하므로 protected를 쓴다.
protected Member() {
}
public Member(String username) {
this.username = username;
}
}
MemberJpaRepositoryTest
package study.datajpa.repository;
// junit의 jupiter test
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import study.datajpa.entity.Member;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
// Transactional을 걸고 밑에 비즈니스를 돌린다.
@Transactional
class MemberJpaRepositoryTest {
@Autowired
MemberJpaRepository memberJpaRepository;
@Test
public void testMember() {
Member member = new Member("memberA");
Member savedMember = memberJpaRepository.save(member);
Member findMember = memberJpaRepository.find(savedMember.getId());
// 검증
assertThat(findMember.getId()).isEqualTo(member.getId());
assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
}
}
빌드 로그를 보면 테이블을 만든다.
create table member (
id bigint not null,
username varchar(255),
primary key (id)
)
db에서 확인을 할려면 @Rollback(false)를 넣어준다.(실무에서는 @Rollback(false)를 빼준다.)
package study.datajpa.repository;
// junit의 jupiter test
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import study.datajpa.entity.Member;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
// Transactional을 걸고 밑에 비즈니스를 돌린다.
@Transactional
// 다 rollback을 시켜버리고 jpa의 영속성 컨텍스트도 flush를 안한다.
// db에 아무쿼리도 보내지 않는다.
@Rollback(false)
class MemberJpaRepositoryTest {
@Autowired
MemberJpaRepository memberJpaRepository;
@Test
public void testMember() {
Member member = new Member("memberA");
Member savedMember = memberJpaRepository.save(member);
Member findMember = memberJpaRepository.find(savedMember.getId());
// 검증
assertThat(findMember.getId()).isEqualTo(member.getId());
assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
}
}
그러면 아래처럼 insert 쿼리문이 나오게 된다.
insert
into
member
(username, id)
values
(?, ?)
isEqualTo를 넣어주면 값이 같게 나오게 된다.
package study.datajpa.repository;
// junit의 jupiter test
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
import study.datajpa.entity.Member;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
@Rollback(false)
class MemberJpaRepositoryTest {
@Autowired
MemberJpaRepository memberJpaRepository;
@Test
public void testMember() {
Member member = new Member("memberA");
Member savedMember = memberJpaRepository.save(member);
Member findMember = memberJpaRepository.find(savedMember.getId());
// 검증
assertThat(findMember.getId()).isEqualTo(member.getId());
assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
assertThat(findMember).isEqualTo(member);
}
}
Spring data jpa를 만들자. MemberRepository를 인터페이스로 만들고
MemberRepositoryTest도 만들어준다.
아래와 같이 설정을 해주고 빌드해주면 MemberRepositoryTest를 할 때와 같은 결과가 나온다.
// MemberRepository
package study.datajpa.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import study.datajpa.entity.Member;
public interface MemberRepository extends JpaRepository<Member, Long> {
}
// MemberRepositoryTest
package study.datajpa.repository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
import study.datajpa.entity.Member;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
@Rollback(false)
class MemberRepositoryTest {
@Autowired
MemberRepository memberRepository;
@Test
public void testMember() {
Member member = new Member("memberA");
Member savedMember = memberRepository.save(member);
Member findMember = memberRepository.findById(savedMember.getId()).get();
assertThat(findMember.getId()).isEqualTo(member.getId());
assertThat(findMember.getUsername()).isEqualTo(member.getUsername());
assertThat(findMember).isEqualTo(member);
}
}
drop table if exists member CASCADE
2022-04-15 17:33:23.684 DEBUG 11328 --- [ main] org.hibernate.SQL :
drop sequence if exists hibernate_sequence
2022-04-15 17:33:23.686 DEBUG 11328 --- [ main] org.hibernate.SQL : create sequence hibernate_sequence start with 1 increment by 1
2022-04-15 17:33:23.688 DEBUG 11328 --- [ main] org.hibernate.SQL :
create table member (
id bigint not null,
username varchar(255),
primary key (id)
)
insert
into
member
(username, id)
values
(?, ?)
application.yml을 org.hibernate.type: trace를 true로 해주고
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/datajpa
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
# show_sql: true
format_sql: true
logging.level:
org.hibernate.SQL: debug
org.hibernate.type: trace
build.gradle에서 dependencies에서 아래를 추가해준다.
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.7'
그러면 빌드로그가 insert에서는 (?, ?)가 나오고 create에서는 p6spy가 나오면서 아래와 같아진다.
create table member (
id bigint not null,
username varchar(255),
primary key (id)
)
2022-04-15 17:39:05.394 INFO 11403 --- [ main] p6spy : #1650011945394 | took 1ms | statement | connection 2| url jdbc:h2:tcp://localhost/~/datajpa
create table member (
id bigint not null,
username varchar(255),
primary key (id)
)
create table member (
id bigint not null,
username varchar(255),
primary key (id)
);
insert
into
member
(username, id)
values
(?, ?)
<출처 김영한: 실전! 스프링 데이터 JPA >
실전! 스프링 데이터 JPA - 인프런 | 강의
스프링 데이터 JPA는 기존의 한계를 넘어 마치 마법처럼 리포지토리에 구현 클래스 없이 인터페이스만으로 개발을 완료할 수 있습니다. 그리고 반복 개발해온 기본 CRUD 기능도 모두 제공합니다.
www.inflearn.com
'Spring > SpringDataJPA' 카테고리의 다른 글
메소드 이름으로 쿼리 생성 (0) | 2022.04.15 |
---|---|
공통 인터페이스 분석 (0) | 2022.04.15 |
공통 인터페이스 설정 & 적용 (0) | 2022.04.15 |
공통 인터페이스 기반 - 순수 JPA 기반 레포지토리 만들기 (0) | 2022.04.15 |
예제 도메인 모델 - 예제 도메인 모델과 동작확인 (0) | 2022.04.15 |