Skip to content

Commit

Permalink
✨ Feature/235 주간 베스트 레시피 batch 세팅
Browse files Browse the repository at this point in the history
  • Loading branch information
Hanvp committed Oct 22, 2023
1 parent 8320c87 commit a230619
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 1 deletion.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.3.1.RELEASE'
implementation platform("org.springframework.cloud:spring-cloud-dependencies:2021.0.5")

implementation 'org.springframework.boot:spring-boot-starter-batch'
implementation 'org.springframework.boot:spring-boot-starter-quartz'
testImplementation 'org.springframework.batch:spring-batch-test'

// queryDSL 설정
implementation "com.querydsl:querydsl-jpa"
implementation "com.querydsl:querydsl-core"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package zipdabang.server;

import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableFeignClients
@EnableJpaAuditing
@EnableRedisRepositories
@EnableBatchProcessing
@EnableScheduling
public class ZipdabangServerApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package zipdabang.server.batch.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.data.RepositoryItemReader;
import org.springframework.batch.item.data.builder.RepositoryItemReaderBuilder;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.Sort;
import zipdabang.server.domain.recipe.Recipe;
import zipdabang.server.domain.recipe.WeeklyBestRecipe;
import zipdabang.server.repository.recipeRepositories.RecipeRepository;
import zipdabang.server.repository.recipeRepositories.WeeklyBestRecipeRepository;

import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Configuration
@EnableBatchProcessing
@RequiredArgsConstructor
public class WeeklyBestRecipeBatchConfig {

private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
private final RecipeRepository recipeRepository;
private final WeeklyBestRecipeRepository weeklyBestRecipeRepository;

@Value("10")
private Integer chunkSize;

@Bean
public Job job() {
Job job = jobBuilderFactory.get("WeeklyBestRecipeJob")
.start(step1())
.next(step2())
.next(step3())
.build();

return job;
}

@Bean
public Step step1() {
return stepBuilderFactory.get("WeeklyBestRecipeStep1")
.<WeeklyBestRecipe, WeeklyBestRecipe>chunk(5)
.reader(step1ItemReader())
.writer(step1ItemWriter())
.build();
}

@Bean
public Step step2() {
return stepBuilderFactory.get("WeeklyBestRecipeStep2")
.<Recipe, WeeklyBestRecipe>chunk(chunkSize)
.reader(step2ItemReader())
.processor(step2ItemProcessor())
.writer(step2ItemWriter())
.build();
}

@Bean
public Step step3() {
return stepBuilderFactory.get("WeeklyBestRecipeStep3")
.<Recipe, Recipe>chunk(chunkSize)
.reader(step3ItemReader())
.writer(step3ItemWriter())
.build();
}

@StepScope
@Bean
public ListItemReader<WeeklyBestRecipe> step1ItemReader() {
return new ListItemReader<WeeklyBestRecipe>(weeklyBestRecipeRepository.findAll());
}

@StepScope
@Bean
public ItemWriter<WeeklyBestRecipe> step1ItemWriter() {
return bestRecipes -> bestRecipes.forEach(bestRecipe -> weeklyBestRecipeRepository.delete(bestRecipe));
}

@StepScope
@Bean
public ListItemReader<Recipe> step2ItemReader() {
return new ListItemReader<Recipe>(recipeRepository.findTop5ByOrderByWeekLikeDescWeekScrapDescTotalLikeDescTotalScrapDesc());
}

@StepScope
@Bean
public ItemProcessor<Recipe, WeeklyBestRecipe> step2ItemProcessor() {
AtomicInteger index = new AtomicInteger(1);

return recipe -> WeeklyBestRecipe.builder()
.ranking(index.getAndIncrement())
.recipe(recipe)
.build();
}

@StepScope
@Bean
public ItemWriter<WeeklyBestRecipe> step2ItemWriter() {
return bestRecipes -> bestRecipes.forEach(bestRecipe -> weeklyBestRecipeRepository.save(bestRecipe));
}

@StepScope
@Bean
public ListItemReader<Recipe> step3ItemReader() {
return new ListItemReader<Recipe>(recipeRepository.findAll());
}

@StepScope
@Bean
public ItemWriter<Recipe> step3ItemWriter() {
return recipes -> recipes.forEach(recipe -> recipeRepository.updateWeeklyData(recipe));
}
}
40 changes: 40 additions & 0 deletions src/main/java/zipdabang/server/batch/schedular/BatchScheduler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package zipdabang.server.batch.schedular;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import zipdabang.server.batch.config.WeeklyBestRecipeBatchConfig;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
@RequiredArgsConstructor
public class BatchScheduler {

private final JobLauncher jobLauncher;
private final WeeklyBestRecipeBatchConfig weeklyBestRecipeBatchConfig;

// @Scheduled(cron = "0 0 0 ? ? 1")
@Scheduled(cron = "0 0 0 * * 1")
public void runWeeklyBestRecipeJob() {
Map<String, JobParameter> confMap = new HashMap<>();
confMap.put("time", new JobParameter(System.currentTimeMillis()));
JobParameters jobParameters = new JobParameters(confMap);

try {
jobLauncher.run(weeklyBestRecipeBatchConfig.job(), jobParameters);
} catch (JobExecutionAlreadyRunningException | JobInstanceAlreadyCompleteException
| JobParametersInvalidException | org.springframework.batch.core.repository.JobRestartException e) {
log.error(e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ public class WeeklyBestRecipe extends BaseEntity {
private Recipe recipe;

private Integer ranking;
private Integer preRanking;
// private Integer preRanking;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import zipdabang.server.domain.member.Member;
import zipdabang.server.domain.recipe.Recipe;

Expand All @@ -20,4 +22,10 @@ public interface RecipeRepository extends JpaRepository<Recipe, Long> {
List<Recipe> findTop5ByMemberOrderByCreatedAtDesc(Member member);

Page<Recipe> findByMember(Member member, PageRequest pageRequest);

List<Recipe> findTop5ByOrderByWeekLikeDescWeekScrapDescTotalLikeDescTotalScrapDesc();

@Modifying
@Query("UPDATE Recipe r SET r.weekLike = 0, r.weekScrap = 0, r.weekView = 0 WHERE r = :recipe")
void updateWeeklyData(Recipe recipe);
}

0 comments on commit a230619

Please sign in to comment.