항상 Java로만 개발하다가 Kotlin을 사용하여 프로젝트를 진행한 적이 있다.
이 때 SpringBoot 3버전을 처음 사용해봤는데 설정 방식이 기존 방식과 다르거나 Java와 사용법이 다른 부분들이 있어 몇 가지 정리해 보았다.
코드는 IntelliJ에서 작성된 것임을 참고하자.
Querydsl 설정하기 (23.2 기준)
우선 Springboot 버전이 변경되면서 javax가 아닌 jakarta로 변경되었다.
- build.gradle.kts
plugins{
...
kotlin("kapt")version"1.7.10"
}
dependencies {
implementation("com.infobip:infobip-spring-data-jpa-querydsl-boot-starter:8.1.0")
kapt("com.querydsl:querydsl-apt:5.0.0:jakarta")
kapt("org.springframework.boot:spring-boot-configuration-processor")
}
기존과는 다르게 Q객체가 만들어지는 경로는 별도로 지정해 줄 필요가 없다.
- QuerydslConfig.kt
package com.aceent.y23okr.config
import com.querydsl.jpa.impl.JPAQueryFactory
import jakarta.persistence.EntityManager
import jakarta.persistence.PersistenceContext
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class QuerydslConfig (
@PersistenceContext
private val entityManager: EntityManager
) {
@Bean
fun jpaQueryFactory(): JPAQueryFactory {
return JPAQueryFactory(this.entityManager)
}
}
설정이 끝난 뒤 Gradle → Tasks - build - clean 한 뒤 other - compileKotlin 실행해서 Q객체 만들어지는지 확인해보자.
참고로 나같은 경우 Autowired 문제가 발생했는데 이는 인텔리제이 버그였고 최신 버전으로 업데이트하니 에러가 사라졌다.
Querydsl을 Kotlin으로 개발하다보니 Java로 개발할 때와 차이점이 있었다.
내가 사용하면서 다른 점 몇 가지를 정리해봤다.
Kotlin과 Java의 차이?
1. subquery 사용
var subQuery: JPQLQuery<Long>? = JPAExpressions.select(qResult.count())
.from(qResult)
.where(qResult.resultId.eq(qResult.resultId))
JPAExpressions를 사용하여 필요한 코드를 작성했다.
2. alias 지정
ExpressionUtils.`as`(subQuery, alias명)
subQuery 자리에 alias를 지정하고 싶은 코드를 작성하면 되며 alias명 자리에 alias명을 지정해주면 된다.
나는 별칭을 지정하고 싶은 코드가 서브쿼리여서 subQuery로 따로 선언해 준 뒤 alias명을 지정했다.
3. 컬렉션 함수 사용
Kotlin과 Java 코드 비교
- Kotlin
fun getProducts(productIds: Set<Long?>?): Map<Long?, ProductResponse?>? {
val converter = Mappers.getMapper(ProductMapper::class.java)
return productRepo.findByProductIdIn(productIds)?.map { converter.convertProductListDto(it) }
?.associate { (it?.productId ?: 0) to it}
}
- Java
public Map<Long, ProductListDto> getProduct(Set<Long> productIds) {
return productRepo.findByProductIdIn(productIds).stream().map(Product::convertListDto)
.collect(Collectors.toMap(ProductListDto::getProductId, Function.identity()));
}
Kotlin에서는 stream을 사용할 필요 없이 조금 더 간결한 컬렉션 함수를 제공한다.
Kotlin에서 사용된 associate에 대해 간단하게 알아보자.
- 어떤 데이터를 Map으로 만들어 key, value로 묶어줄 수 있다.
- Pair의 형태로 key와 value를 만든다.
- List를 Map 형태로 변형시킬 수 있다.
4. 문자열 비교
대소문자를 구분하지 않고 문자열을 비교할 때 사용법이 달랐다.
코드를 비교해보자.
- Kotlin
@JsonCreator
open fun of(name: String?): UIType? {
for (obj in values()) {
if (obj.name.equals(name, ignoreCase = true)) {
return obj
}
}
return null
}
Kotlin에서는 equals에서 ignoreCase = true를 지정해주면 된다.
- Java
@JsonCreator
public static City of(String name) {
for (City obj : City.values()) {
if (obj.name().equalsIgnoreCase(name)) {
return obj;
}
}
return null;
}
Java에서는 equalsIgnoreCase를 사용하면 된다.
Kotlin을 사용하면서 Java와 비슷한듯 많이 다른 문법에 처음에는 좀 헤매면서 개발을 진행했다.
하다보니 조금 더 간결한 코드에 익숙해지면 편리할 것 같다는 생각을 했지만 확실히 아직은 Java가 편하다..
부족한 부분이 많은 Kotlin 내용 정리이지만 나중에 다시 코틀린에 도전할 나한테도 도움이 되길 바라며 글 마친다! 망망
'개발' 카테고리의 다른 글
파일럿 프로젝트 시작하기 - 프로젝트 세팅 (0) | 2023.08.16 |
---|---|
mariadb - DB 생성 및 IntelliJ 연동 (0) | 2023.07.20 |
Docker로 mariadb 사용하기 (0) | 2023.07.19 |
Swagger 적용하기 - SpringBoot3 버전 (0) | 2023.07.18 |
Swagger 적용하기 - spring fox (0) | 2023.07.17 |