최신 프로젝트에서 Spring Data 시리즈
, JPA
, QueryDSL
스택을 사용하다보니, 같이 개발하는 후임들이 기술을 못따라오는 현상이 생겼습니다.
이 내용에 대해서는 다룰 내용이 많아 추가적인 포스팅에서 작성하겠습니다.
잡설은 각설하고 JPA 및 QueryDSL 설정 및 개발 가이드라인에 대해 작성하겠습니다.
먼저 QueryDSL을 사용하기 전에 jpa
와 querydsl
관련 의존성과 플러그인을 설정합니다.
Maven
을 많이 사용하기 때문에 Maven
기준으로 작성했습니다.pom.xml
에서 아래 코드를 추가해줍니다. <!-- JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- QueryDSL APT Config -->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
<!-- QueryDSL JPA Config -->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<plugins>
....
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
....
<plugins>
JPAQueryFactory 전역 Bean을 생성합니다.
@Configuration
public class QueryDslConfiguration {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
Entity User
생성합니다.
@Entity
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "rec_key")
private Long recKey;
@Column(name = "user_id", length = 20, nullable = false)
private String userId;
@Column(name = "user_name", length = 20, nullable = false)
private String userName;
@Column(name = "create_date")
@Builder.Default
private LocalDateTime createDate = LocalDateTime.now();
@Column(name = "edit_date")
private LocalDateTime editDate = LocalDateTime.now();
}
Maven
> 소스 및 업데이트 폴더 생성
target
> classes
> 패키지 경로
에서 QClass 생성 유무를 확인합니다.
=> User
, QUser
클래스 확인
public interface UserRepository extends CrudRepository<User, Long>, UserRepositoryCustom {
@Override
List<User> findAll();
}
public interface UserRepositoryCustom {
Page<User> findAllBy(UserSearchParam param);
}
이 구현체 실제 QueryDSL
을 사용한 코드를 작성합니다.
@RequiredArgsConstructor
public class UserRepositoryCustomImpl implements UserRepositoryCustom {
private final JPAQueryFactory queryFactory;
public List<User> getUserList() {
QUser user = QUser.user;
return queryFactory
.select(user)
.from(user)
.fetch();
}
}
UserRepository
가 UserRepositoryCustom
을 상속받았기 때문에, 따로 메소드를 추가해주지 않아도 원래 Repository의 메소드인 것처럼 사용할 수 있습니다.
@Service
@AllArgsConstructor
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
@Override
public PageVO<User> findAll() {
return PageVO.builder(userRepository.findAll()).build();
}
@Override
public PageVO<User> findAllBy(UserSearchParam param) {
return PageVO.builder(userRepository.findAllBy(param)).build();
}
}