본문 바로가기
개발 관련 공부/JPA

spring boot+mysql+jpa+querydsl 테스트

by 슴새 2023. 2. 19.
반응형

말 그대로 테스트를 위한거라 이상하거나 틀린 부분이 있을 수 있음

 

기본 세팅

spring boot starter에서 적당히 만든다.

 

create database testdb;
use testdb;
CREATE TABLE `test` (
	`id`	int not null auto_increment primary key,
	`name`	varchar(50)	NULL 
);
 
INSERT INTO `test`(`name`) VALUES('안녕');
INSERT INTO `test`(`name`) VALUES('안녕2');
INSERT INTO `test`(`name`) VALUES('하이룽');

db 적당히 만든다.

jpa가 만들게 할수도 있지만 지금은 미리 만들어놓은 애랑 연결되게 하겠슴

 

server.port=9999

#db
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/testdb?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=계정명
spring.datasource.password=비번

# JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.data.jpa.repositories.enabled=true

application.properties 작성

plugins {
	id 'java'
	id 'org.springframework.boot' version '2.7.8'
	id 'io.spring.dependency-management' version '1.0.15.RELEASE'

	//querydsl 추가
	id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}

group = 'com.example'
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'
	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'com.mysql:mysql-connector-j'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'

	//querydsl 추가
	implementation "com.querydsl:querydsl-jpa:5.0.0"
	implementation "com.querydsl:querydsl-apt:5.0.0"
}

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

//--querydsl 추가--
def querydslDir = "$buildDir/generated/querydsl"

querydsl {
	jpa = true
	querydslSourcesDir = querydslDir
}
sourceSets {
	main.java.srcDir querydslDir
}
compileQuerydsl{
	options.annotationProcessorPath = configurations.querydsl
}
configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
	querydsl.extendsFrom compileClasspath
}
//--querydsl 추가 끝--

stater에 querydsl 관련은 없기 때문에...

손수 build.gradle에 추가해준다. 

폴더 구조 적당히 생성한다.

 

 

코드 작성

config 폴더

@EnableJpaAuditing
@Configuration
public class QueryDslConfig {

    @PersistenceContext
    private EntityManager entityManager;

    public QueryDslConfig() {
    }

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(this.entityManager);
    }
}

 

controller 폴더

@RestController
@RequestMapping("/test")
@RequiredArgsConstructor
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class testController {

    private final testService service;

    //api 정상 동작 확인용- hello 문자열을 반환한다.
    @GetMapping("/hello")
    public String Hello(){
        return "hello";
    }

    //jap 기본 쿼리 메서드 확인용 - 테스트 테이블의 칼럼 수를 반환한다.
    @GetMapping("/testDefault")
    public long getCount(){
        return service.getCount();
    }

    //jpa 커스텀 쿼리 메서드 동작 확인용. 이름에 '안녕'을 포함하는 칼럼을 반환한다.
    @GetMapping("/testCustom")
    public List<test> getTest(){
        return service.getCustom("안녕");
    }

    //jpa querydsl 동작 확인용. 모든 칼럼을 반환한다.
    @GetMapping("/testQueryDsl")
    public List <test> getQueryDsl(){
        return service.getQueryDsl();
    }

}

기본 동작 확인용 api - hello 문자열을 반환

jpa 기본 쿼리 메서드 확인용 api - test 테이블의 칼럼 개수를 반환

jpa 커스텀 쿼리 메서드 확인용 api - name에 '안녕'을 포함하는 칼럼들을 반환 

jpa+querydsl 동작 확인용 api -  모든 칼럼을 반환 (칼럼 2개짜리 테이블 가지고 만들만한 복잡한 쿼리문이 생각이 안났음..)

 

총 4개를 만들어주었다.

 

 

dto 폴더

@Entity
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class test {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

}

폴더명을 dto 말고 entity로 짓는게 더 정확한 의미같은데..

다음부턴 entity로 짓자

repository 폴더

 

public interface testRepository extends JpaRepository<test, Long> {
    //커스텀 쿼리 메서드
    List<test> findByNameContaining(String name);
}

기본 jpa용 레포

 

public interface querydslRepository {
    List<test> getList();
}
@RequiredArgsConstructor
@Repository
public class querydslRepostoryImpl implements querydslRepository {


    private final JPAQueryFactory jpaQueryFactory;

    @Override
    public List<test> getList() {
        Qtest qtest = Qtest.test;
        return jpaQueryFactory
                .selectFrom(qtest)
                .fetch();

    }
}

querydsl용 레포

 

service 폴더

public interface testService {
    long getCount();
    List<test> getCustom(String name);
    List <test> getQueryDsl();
}
@Service
@Transactional
@RequiredArgsConstructor
public class testServcieImpl implements testService{

    private final testRepository jpaRepo;
    private final querydslRepository queryRepo;
    @Override
    public long getCount() {
        return jpaRepo.count();
    }

    @Override
    public List<test> getCustom(String name) {
        return jpaRepo.findByNameContaining(name);
    }

    @Override
    public List<test> getQueryDsl() {
        return queryRepo.getList();
    }


}

여기까지 하면 코드 작성은 끝났고

gradle 탭에 가서 ohter-compileQuerydsl를 실행한 뒤QClass가 생긴걸 확인해준다.

 

결과 확인

기본 동작 확인용 api

 

jpa 기본 쿼리문 확인용 api(칼럼 개수 반환)

 

jpa 커스텀 쿼리문 확인용 api(이름에 '안녕' 포함하는 칼럼들 반환)

 

querydsl 확인용 api (모든 칼럼 반환)

실전에선 jpa 기본 쿼리문이나 커스텀 쿼리문으로 해결하기 힘든 복잡한 쿼리문에 사용하기

 

 

반응형

'개발 관련 공부 > JPA' 카테고리의 다른 글

jpa @OnDelete...  (0) 2023.03.24

댓글