728x90
환경
IDE: intellij
SpringBootVersion: 3.0.11
Gradle: 8.8
Java: 17
build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "3.0.11"
id("io.spring.dependency-management") version "1.1.0"
kotlin("jvm") version "1.7.22"
kotlin("plugin.spring") version "1.7.22"
kotlin("plugin.jpa") version "1.7.22"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-batch")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.springframework.kafka:spring-kafka:3.2.0")
implementation("mysql:mysql-connector-java:8.0.33")
implementation("com.querydsl:querydsl-jpa:5.0.0:jakarta")
implementation("com.querydsl:querydsl-kotlin:5.0.0")
annotationProcessor("com.querydsl:querydsl-apt:5.0.0:jakarta")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.batch:spring-batch-test")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
Entity
import jakarta.persistence.*
import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.LastModifiedDate
import org.springframework.data.jpa.domain.support.AuditingEntityListener
import java.time.LocalDateTime
@Entity
@EntityListeners(AuditingEntityListener::class)
data class House(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
val address: String,
val price: Double,
@CreatedDate
@Column(nullable = false, updatable = false)
var createdAt: LocalDateTime? = null,
@LastModifiedDate
@Column(nullable = false)
var updatedAt: LocalDateTime? = null,
@Column(nullable = true)
var deletedAt: LocalDateTime? = null
)
Repository
@Repository
interface HouseRepository : JpaRepository<House, Long> {
fun findByCreatedAtBetween(
startDateTime: LocalDateTime,
endDateTime: LocalDateTime,
pageable: Pageable
): Page<House>
}
Job
import com.example.kotlinsimplespringbatch.domain.House
import org.springframework.batch.core.Job
import org.springframework.batch.core.Step
import org.springframework.batch.core.job.builder.JobBuilder
import org.springframework.batch.core.repository.JobRepository
import org.springframework.batch.core.step.builder.StepBuilder
import org.springframework.batch.item.Chunk
import org.springframework.batch.item.data.RepositoryItemReader
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.transaction.PlatformTransactionManager
@Configuration
class HouseCreationConfigJobConfig(
private val jobRepository: JobRepository,
private val transactionManager: PlatformTransactionManager,
@Qualifier("houseCreationConfirmItemReader")
private val houseCreationConfirmItemReader: RepositoryItemReader<House>
) {
val chunkSize: Int = 500
val jobName = "houseCreationConfirmJob"
@Bean
fun houseCreationConfirmJob(houseCreationConfirmStep: Step): Job {
return JobBuilder(jobName, jobRepository)
.start(houseCreationConfirmStep)
.build()
}
@Bean
fun houseCreationConfirmStep(): Step {
return StepBuilder("houseCreationConfirmStep", jobRepository)
.chunk<House, House>(chunkSize,transactionManager)
.reader (houseCreationConfirmItemReader)
.writer { chunk: Chunk<out House> ->
chunk.items.forEach { house ->
println("Writing house: $house")
}
}
.build()
}
}
Reader
import com.example.kotlinsimplespringbatch.adapter.repository.HouseRepository
import com.example.kotlinsimplespringbatch.domain.House
import org.springframework.batch.item.data.RepositoryItemReader
import org.springframework.batch.item.data.builder.RepositoryItemReaderBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.domain.Sort
import java.time.*
@Configuration
class HouseCreationConfirmItemReaderConfig {
val chunkSize: Int = 500
private final val zoneId: ZoneId = ZoneId.of("Asia/Seoul")
val startDateTime: LocalDateTime = LocalDate.now(zoneId)
.atStartOfDay()
val endDateTime: LocalDateTime = LocalDate.now(zoneId)
.plusDays(1)
.atStartOfDay()
@Bean
fun houseCreationConfirmItemReader(houseRepository: HouseRepository): RepositoryItemReader<House> {
return RepositoryItemReaderBuilder<House>()
.name("houseCreationItemReader")
.repository(houseRepository)
.methodName("findByCreatedAtBetween")
.arguments(listOf(startDateTime, endDateTime))
.pageSize(chunkSize)
.sorts(mapOf("id" to Sort.Direction.ASC))
.build()
}
}
'스프링 프레임워크 > springbatch' 카테고리의 다른 글
스프링배치 FlatFileItemReader 시작하기 (0) | 2024.08.07 |
---|---|
스프링배치 tasklet기반 step 시작하기 (0) | 2024.08.06 |
spring batch 시작하기 (0) | 2024.07.31 |
springbatch5 h2 database 특정 job 테스트하기 (0) | 2024.07.09 |