[스터디] Query DSL 기초 (2) - 실습

2023. 2. 10. 19:31BackEnd/DataBase

작성자알 수 없는 사용자

728x90
반응형

안녕하세요. 기깔사에서 프로젝트를 수행하기 위해 꼭 필요한 개념을 같이 공부하게 된 제시Ca 입니다!

지난 1편에서 설정한 프로젝트 설정을 기반으로 Query DSL을 이용해서 

Q-type class를 만들고, H2 DB를 설정해서 CRUD를 구현해보겠습니다.

 

Q-Class (Q-Type)이란?

컴파일 시점에 JPAAnnotationProcessor가 동작하게 되면, 해당 APT(주석 처리 도구)가 @Entity와 같은 어노테이션을 찾습니다. 그 내용을 분석하며, 'Q' 가 접두사로 붙는 클래스를 생성하게 되는데, Entity 와 최대한 비슷한 패키지 구조로 유지합니다. (이 접두어 Q는 수정할 수도 있습니다.) 

이때 생성된 class를 Q-Class 혹은 Q-Type이라고 합니다.

이 Q-Class는 정적으로 접근해서 사용할 수 있는 인스턴스를 가지고 있어서, 어디서든 사용할 수 있어서, 사용을 편하게 해줍니다.

 

이 Q class가 생성되는지 보기 위해, 먼저 Entity를 만들어줍니다.

package study.querydsl.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import lombok.Data;

@Entity
@Data
public class HelloWorld {

	@Id @GeneratedValue
	private String id;
}

 간단하게 id 인스턴스 하나만 가진 HelloWorld Entity를 생성했습니다.

 

빌드 시에 자동 생성되는 Q class를 확인하기 위해서, gradle를 build 해보겠습니다.

저는 IDE로 STS를 사용하고 있습니다.

 

Gradle Task 창에서 build > jar를 더블 클릭하면 gradle 빌드가 시작됩니다.

빌드가 성공으로 끝난다면 아래 화면과 같이 build 패스를 설정한 패키지 하위 그대로 QHelloWorld.class가 생성된 것을 

확인할 수가 있어요!

만일, 패키지가 보이지 않는다면, build path를 설정해주면 됩니다.

 

H2 DB 설정하기

https://www.h2database.com/html/main.html

 

H2 Database Engine

H2 Database Engine Welcome to H2, the Java SQL database. The main features of H2 are: Very fast, open source, JDBC API Embedded and server modes; in-memory databases Browser based Console application Small footprint: around 2.5 MB jar file size     Supp

www.h2database.com

홈페이지에 접속해서 Download 에 접속해 상황에 맞는 파일로 다운받아 설치합니다.

저는 Windows 라서 Windows Installer로 다운받아서, exe를 더블클릭해 폴더를 지정하고 설치했습니다.

설치된 경로에 가면 H2 라는 폴더로 생성되어있을 거에요 

 

bin/h2w.bat을 실행하면 아래처럼 화면이 나오고, 연결을 하면 생성됩니다.

 

생성이 되면 아래처럼 접속을 할 수 있습니다.

이후는 jdbc:h2:tcp://localhost/~/정한이름 으로 접속이 가능합니다.

 

프로젝트로 다시 돌아와서, application.yml에 설정을 아래와 같이 해줍니다.

spring:
 datasource:
 url: jdbc:h2:tcp://localhost/~/설정이름
 username: sa
 password:
 driver-class-name: org.h2.Driver
 jpa:
 hibernate:
 ddl-auto: create
 properties:
 hibernate:
 format_sql: true

설정한 후 refresh 하고, 프로젝트를 실행해봅니다.

 

이전에 테스트로 만들었던 HelloWord Entity는 그대로 사용하려고 합니다.

대신 몇가지를 더 수정 해주었습니다.

생성자 추가하고,  db랑 연결하기 위한 colum명 기입했습니다.

package study.querydsl.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Data;
	
@Entity
@Data
@AllArgsConstructor
public class HelloWorld {

	@Id 
	@Column(name="id")
	private String id;
	
	
}

먼저 생성을 위해 테스트 코드를 작성합니다.

테스트 코드는 src/test/java 하위에 작성을 합니다.

 

package study.querydsl.entity;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

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.Commit;

import com.querydsl.jpa.impl.JPAQueryFactory;

@SpringBootTest
@Transactional
@Commit
public class HelloWorldTest {

	@Autowired
	EntityManager em;
	
	@Test
	public void testEntity() {
		
		try {
			HelloWorld helloA = new HelloWorld("A");
			HelloWorld helloB = new HelloWorld("b");
			
			em.persist(helloA);
			em.persist(helloB);
			
			JPAQueryFactory query = new JPAQueryFactory(em);
			QHelloWorld qhello = QHelloWorld.helloWorld;
					
			List<HelloWorld> list = query.selectFrom(qhello).fetch();
										
			for (HelloWorld helloWorld : list) {
				System.out.println("helloWorld=" + helloWorld);
			}
						
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

테스트 코드를 실행하고 나면, 아래와 같이 콘솔에 query  실행문이 어떻게 됬는지 보여줍니다.

insert가 되었고, 아래 조회하는 쿼리에도 값이 잘 출력되고 있습니다.

insert가 되었는지 실제 테이블을 확인해보러 H2 페이지로 갑니다.

결과물이 잘 나오는지 확인하면 이제 다음 update, delete 작업을 해봐야겠죠?

 

나머지 테스트 코드를 작성해줍니다.

@Test
	public void updateEntity() {		
		try {
			
			HelloWorld helloA = new HelloWorld("A");
			HelloWorld helloB = new HelloWorld("b");
			
			em.persist(helloA);
			em.persist(helloB);
			
			JPAQueryFactory query = new JPAQueryFactory(em);
			
			QHelloWorld qhello = QHelloWorld.helloWorld;

			
			query
				.update(qhello)
			    .set(qhello.id, "new")
			    .where(qhello.id.eq(helloA.getId()))
			    .execute();
						
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

A값을 가지고 있던 것이 new라는 새로운 문자열로 바뀐 것을 볼 수 있습니다.

이제 A와 b를 넣고 b를 삭제해 볼거에요 

@Test
	public void deleteEntity() {
		try {
			HelloWorld helloA = new HelloWorld("A");
			HelloWorld helloB = new HelloWorld("b");
			
			em.persist(helloA);
			em.persist(helloB);
			
			QHelloWorld qhello = QHelloWorld.helloWorld;
			JPAQueryFactory query = new JPAQueryFactory(em);
						
			query
			.delete(qhello)
	        .where(qhello.id.eq(helloB.getId()))
	        .execute();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

b값을 가진 데이터가 삭제 된 것을 알 수 있어요! 

 

이제 기본적인 CRUD는 이렇게 간단하게 테스트 해봤습니다.

실제 프로젝트는 이보다 더 어려운 Join이나 복잡한 관계의 데이터를 다뤄야해서 어려울 수 있지만, 

차근차근 공부하면 같이 금방 할 수 있겠죠?

 

다음엔 프로젝트에 어떻게 적용되는지 케이스별로 다뤄보는 시간을 갖도록 해요! 

728x90
반응형