Querydsl을 사용하는 이유
JPA(Java Persistence Api)가 제공해주는 CRUD(Create Read Update Delete)를 사용한다고 하더라도
조회하는 데이터가 복잡해지면 복잡해질수록 JPQL(Java Persistence Query Language)가 필연적으로 사용하게 됩니다
쿼리는 문자열로 이루워져있어서 코드를 읽기 힘들게 하고
컴파일 과정에서 오류를 발견하기 어렵고 결과가 나오기 전까지는 검증 또한 어렵습니다
querydsl사용 함으로써 쿼리를 코드 형식으로 작성할 수 있고
코드 형식으로 작성을 하기 때문에 사전에 오류를 먼저 캐치할수 있고
IDE(Intergrated Development Enviroment)의 자동완성 기능을 사용할 수 있으며
동적인 쿼리를 생성하는데 훨씬더 수월하게 할 수 있습니다
설정
maven pom.xml에 의존성 추가
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
플러그인 추가
<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>
maven업데이트 실행
설정을 완료했습니다 Q타입 또한 생성이 되었을겁니다!
Querydsl 사용
먼저 JpaQueryFactory 설정을 해주어야 합니다
spring 에 빈등록을 해서 싱글톤으로 전역으로 사용할 수 있게 해줍시다
또 entityMangerFactory는 어플리케이션에 하나씩만 생성이 되어야 합니다
@Configuration
public class QuerydslConfig {
@PersistenceContext
private EntityManager em;
@Bean
public JPAQueryFactory jpaQueryFactory(){
return new JPAQueryFactory(em);
}
}
EntityManger 는 @PersistenceContext(영속성 컨텍스트)는 영속선 컨텍스트 내에서 관리하고 있는 entity를 주입해주는 어노테이션이고 어플리케이션 동작과 동시에 스프링빈에 등록이 되어 있다고 합니다
이제 예제를 위해 간단한 entity를 생성하겠습니다
@Getter
@Setter
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
private long id;
@Column(columnDefinition = "VARCHAR(16)")
private String userId;
@Column(columnDefinition = "VARCHAR(16)")
private String username;
public User(String userId, String username) {
this.userId = userId;
this.username = username;
}
}
repository도 필요하겠죠
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
이제 QuerydslRepository를 상속받아서 사용해보겠습니다
import static com.example.blog.domain.QUser.user;
import com.example.blog.domain.User;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class UserRepositorySupport extends QuerydslRepositorySupport {
private final JPAQueryFactory queryFactory;
public UserRepositorySupport(JPAQueryFactory queryFactory) {
super(User.class);
this.queryFactory = queryFactory;
}
public List<User> findByUserId(String userId){
return queryFactory
.selectFrom(user)
.where(user.userId.eq(userId))
.fetch();
}
}
Quser 사용합니다
내부에 static으로 정의되어있습니다 QUser의 user를 static으로 import해주시면 됩니다
//물론
Quser.user //사용가능합니다
이제 테스트를 해보도록 하겠습니다
@SpringBootTest
class UserTest {
@Autowired
UserRepository userJpaRepository;
@Autowired
UserRepositorySupport userRepositorySupport;
@Test
public void queryDslTest() {
userJpaRepository.deleteAll();
User user = new User("testId", "testName");
userJpaRepository.save(user);
List<User> result = userRepositorySupport.findByUserId(user.getUserId());
System.out.println(result.size());
System.out.println(result.get(0).getUserId());
}
}
결과
result.size() = 1
result.get(0).getUserId = testId
직관적으로 보기위해 assertThat은 사용하지 않았습니다
결과가 잘 나왔습니다
하지만 위에 코드를 보시면 알겠지만
@Autowired
UserRepository userJpaRepository;
@Autowired
UserRepositorySupport userRepositorySupport;
두개의 repository를 받아야 한다는 것입니다
조금더 나은 코드로 수정을 해야겠네요
두개의 코드를 하나로 합치겠습니다
먼저 support 클래스를 참고해서
public interface UserRepositoryCustom {
List<User> findByUserId(String userName);
}
custom 인터페이스를 하나 생성해줍니다
구현 클래스도 생성을 해줍니다
public class UserRepositoryImpl implements UserRepositoryCustom {
private JPAQueryFactory queryFactory;
public UserRepositoryImpl(JPAQueryFactory queryFactory) {
super(User.class);
this.queryFactory = queryFactory;
}
@Override
public List<User> findByUserId(String userId) {
return jpaQueryFactory
.selectFrom(user)
.where(user.userId.eq(userId))
.fetch();
}
}
그 뒤에
@Repository
public interface UserRepository extends JpaRepository<User, Long>,UserRepositoryCustom {
}
다중 상속을 해주시면 userRepository에서 다 사용할 수 있게 됩니다
부족한 부분이 있으시다면 댓글 주세요
'spring(스프링)' 카테고리의 다른 글
spring scheduler 사용하기 (0) | 2022.05.26 |
---|---|
spring boot + FCM push하는 방법 (0) | 2022.05.11 |
spring boot와 firebase 연결 방법 (2) (0) | 2022.05.07 |
spring boot와 firebase 연결 방법 (1) (1) | 2022.05.06 |
네이버 영화 검색 오픈 api 사용 방법(with spring) (0) | 2022.05.02 |