Spring Framework/[인프런] 실전! QueryDSL

Chapter 01. QueryDsl 프로젝트 생성 및 환경 설정

계란💕 2023. 4. 9. 16:13

프로젝트 설정

  • dependency: Lombok, JPA, H2, starter
  • 프로젝트 설정: 빌드 실행 배포 => 빌드 도구 => Gradle => 둘다 IntelliJ로 설정한다. 
    • 이렇게 해야 자바로 바로 실행할 수 있어서 속도가 빠르다. 

 

  • builde.gradle 
    • QueryDSL  사용하기 위해 다음과 같이 추가한다. 
    • gradle => clean 
    • gradle => compileQuerydsl
    • 위 내용은  터미널로 다음과 같이 입력하는 것과 같다. 
      • ./gradlew clean compileQuerydsl
    • 메이븐의 경우는 다음과 같이 clean 한 다음(target 폴더를 삭제), compile를 실행한다. 실행하고 나면 target 폴더가 생성되면서 Q클래스가 새롭게 생성된다. 

 

<hide/>
plugins {
	id 'java'
	id 'org.springframework.boot' version '2.2.2.RELEASE'
	id 'io.spring.dependency-management' version '1.0.8.RELEASE'
	id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}

group = 'study'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'com.querydsl:querydsl-jpa'

	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'com.h2database:h2'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation ('org.springframework.boot:spring-boot-starter-test'){
		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
	}
}

tasks.named('test') {
	useJUnitPlatform()
}

test {
	useJUnitPlatform()
}


def querydslDir = "$buildDir/generated/querydsl"
querydsl {
	jpa = true
	querydslSourcesDir = querydslDir
}

sourceSets {
	main.java.srcDir querydslDir
}

configurations {
	querydsl.extendsFrom compileClasspath
}

compileQuerydsl {
	options.annotationProcessorPath = configurations.querydsl
}

 

 

  • 정상적으로 적용되면 다음과 같이 Q 클래스가 자동 생성된다. 
    • Q 타입이 정상으로 동작한다. 

 

 

 

  • H2 데이터베이스를 설치한 다음, 윈도우 환경에서는 다음과 같이 bin 폴더 안에 있는 h2.bat 파일을 실행한다. 
    • cf) H2 데이터베이스는 Java 설치 및 세팅이 되어 있어야 사용 가능하다. 

 

 

  • yml 파일 설정
<hide/>
spring:
  datasource:
    url: jdbc:h2:tcp://localhost/~/querydsl
    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

 

 

  • 아래 창에서 저장 버튼을 한 번 눌러준 다음에 연결해야한다.

 

 

  • 기본 엔티티 생성
    • changeTeam()은 양방향 연관관계를 한 번에 처리한다. (해당 멤버를 매개변수로 넣은 팀으로 바꿔주고 상대 팀에도 해당 멤버를 추가해준다.)
    • 연관관계의 주인은 Member 테이블의 team이고 Team 테이블의 필드 members는 연관관계의 주인이 아니다. 따라서, Member 테이블의 team 만이 데이터베이스의 외래키 값을 변경 가능하고 반대편의 members는 읽기만 가능하다. 
<hide/>
@Entity
@Setter
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "username", "age"})
public class Member {


    @Id
    @GeneratedValue
    private Long id;

    private String username;

    private int age;


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "team_id")
    private Team team;


    public Member(String username) {
        this.username = username;
    }


    public Member(String username, int age) {
        this.username = username;
        this.age = age;
    }

    public Member(String username, int age, Team team) {
        this.username = username;
        this.age = age;
        if (team != null) {
            changeTeam(team);
        }
    }


    public void changeTeam(Team team) {
        this.team = team;
        team.getMembers().add(this);

    }

}

 

 

 

<hide/>

@Entity
@Setter @Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "name"})
public class Team {

    @Id
    @GeneratedValue
    private Long id;

    private String name;


    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();

    public Team(String name) {
        this.name = name;
    }
}

 

 

 

  Ex) 데이터 확인 테스트

  • Member 클래스를 띄운 채로 ctrl + shift  + T 를 눌러서 Member 클래스에 대한 테스트 클래스를 만든다. 
  • (h2 데이터베이스를 띄우지 않은 상태로 애플리케이션을 실행하면 socket time out 오류가 난다. )
  • Spring Data JPA를 쓰지 않고 순수 JPA로 확인한다. 
<hide/>

@SpringBootTest
@Transactional
@Commit
public class MemberTest {

    @PersistenceContext
    EntityManager em;


    @Test
    public void testEntity() {
        Team teamA = new Team("teamA");
        Team teamB = new Team("teamB");
        em.persist(teamA);
        em.persist(teamB);

        Member member1 = new Member("member1", 10, teamA);
        Member member2 = new Member("member2", 20, teamA);
        Member member3 = new Member("member3", 30, teamB);
        Member member4 = new Member("member4", 40, teamB);
        em.persist(member1);
        em.persist(member2);
        em.persist(member3);
        em.persist(member4);

        // 초기화
        em.flush();
        em.clear();

        List<Member> members = em.createQuery("SELECT m FROM Member m", Member.class)
            .getResultList();

        for (Member member : members) {
            System.out.println("member = " + member);
            System.out.println("-> member.team= " + member.getTeam());
        }
    }
}

 

 

출처 -  https://www.inflearn.com/course/querydsl-%EC%8B%A4%EC%A0%84