Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 관리자: 회원 탈퇴 기능 추가 #61

Merged
merged 20 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c31e44c
feat: 관리자 회원관리 삭제 구현
limseohyeon Dec 24, 2024
35d5d71
feat: 관리자 회원관리 삭제
limseohyeon Dec 25, 2024
7f5da85
feat: 관리자 회원관리 삭제 구현
limseohyeon Dec 26, 2024
5bc4172
feat: 관리자 회원관리 삭제 구현
limseohyeon Dec 26, 2024
942a715
feat: 관리자 회원관리 삭제 구현
limseohyeon Dec 26, 2024
59a931d
Merge branch 'main' of https://github.com/prgrms-be-devcourse/NBE2-3-…
limseohyeon Dec 26, 2024
318f4ab
feat: 관리자 회원관리 삭제 구현
limseohyeon Dec 24, 2024
9c0d14a
feat: 관리자 회원관리 삭제
limseohyeon Dec 25, 2024
b979f3c
Delete src/test/java/org/programmers/signalbuddy/domain/member/batch/…
limseohyeon Dec 25, 2024
f7aad02
Delete src/main/java/org/springframework/batch/item/database/builder/…
limseohyeon Dec 25, 2024
9e1fb23
feat: 관리자 회원관리 삭제 구현
limseohyeon Dec 26, 2024
d143b1a
feat: 관리자 회원관리 삭제 구현
limseohyeon Dec 26, 2024
99a8897
feat: 관리자 회원관리 삭제 구현
limseohyeon Dec 26, 2024
8a1bcff
feat: 관리자 회원관리 삭제 구
limseohyeon Dec 26, 2024
20e04b3
feat: 관리자 회원관리 삭제 구현
limseohyeon Dec 26, 2024
eee480a
feat: 관리자 회원관리 삭제
limseohyeon Dec 26, 2024
6ef7e9e
fix: yml 파일의 설정 적용
DongminL Dec 26, 2024
a063fc7
chore: batch 메타 테이블 자동 생성
DongminL Dec 26, 2024
aaa550c
fix: 배치 메타 테이블 truncate 제외
DongminL Dec 26, 2024
e0a0929
fix: OSIV 사용하지 않음
DongminL Dec 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ dependencies {
// Thymeleaf
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'

// Batch
implementation 'org.springframework.boot:spring-boot-starter-batch'
testImplementation 'org.springframework.batch:spring-batch-test'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
public class SignalBuddyApplication {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.programmers.signalbuddy.domain.bookmark.entity;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
Expand All @@ -14,6 +15,8 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.locationtech.jts.geom.Point;
import org.programmers.signalbuddy.domain.basetime.BaseTimeEntity;
import org.programmers.signalbuddy.domain.member.entity.Member;
Expand All @@ -35,7 +38,7 @@ public class Bookmark extends BaseTimeEntity {
@Column(nullable = false)
private String address;

@ManyToOne(fetch = FetchType.LAZY)
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
@JoinColumn(name = "member_id", nullable = false)
private Member member;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.programmers.signalbuddy.domain.member.batch;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import java.time.LocalDateTime;
import lombok.extern.slf4j.Slf4j;
import org.programmers.signalbuddy.domain.member.entity.Member;
import org.programmers.signalbuddy.domain.member.entity.QMember;
import org.programmers.signalbuddy.domain.member.entity.enums.MemberStatus;
import org.springframework.batch.item.ItemReader;

import java.util.List;

@Slf4j
public class CustomReader implements ItemReader<Member> {

private final JPAQueryFactory queryFactory;
private final int pageSize;
private Long lastSeenId;
private List<Member> currentPage;
private int currentIndex;

public CustomReader(EntityManagerFactory entityManagerFactory, int pageSize) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
this.queryFactory = new JPAQueryFactory(entityManager);
this.pageSize = pageSize;
this.lastSeenId = null;
this.currentIndex = 0;
}

@Override
public Member read() {
if (currentPage == null || currentIndex >= currentPage.size()) {
fetchNextPage();
}

if (currentPage == null || currentPage.isEmpty()) {
return null;
}

Member member = currentPage.get(currentIndex);
currentIndex++;
return member;
}

private void fetchNextPage() {
QMember qMember = QMember.member;

currentPage = queryFactory
.selectFrom(qMember)
.where(
lastSeenId != null ? qMember.memberId.gt(lastSeenId) : null,
qMember.memberStatus.eq(MemberStatus.WITHDRAWAL).and(qMember.updatedAt.loe(
LocalDateTime.now().minusMonths(6)))
).orderBy(qMember.memberId.asc())
.offset(0)
.limit(pageSize)
.fetch();
// log.info("마지막으로 읽은 id: " + lastSeenId);

if (!currentPage.isEmpty()) {
lastSeenId = currentPage.get(currentPage.size() - 1).getMemberId();
}
currentIndex = 0;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.programmers.signalbuddy.domain.member.batch;


import jakarta.persistence.EntityManagerFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.programmers.signalbuddy.domain.member.entity.Member;

import org.programmers.signalbuddy.domain.member.repository.MemberRepository;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobScope;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemWriter;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
@RequiredArgsConstructor
@Slf4j
public class JobConfig {

private static final int chunkSize = 10;
private final MemberRepository memberRepository;
private final EntityManagerFactory entityManagerFactory;

@Bean
public Job deleteMemberJob(JobRepository jobRepository,
PlatformTransactionManager transactionManager) {
return new JobBuilder("deleteMemberJob", jobRepository).incrementer(new RunIdIncrementer())
.start(deleteMemberStep(jobRepository, transactionManager)).build();
}

@Bean
@JobScope
public Step deleteMemberStep(JobRepository jobRepository,
PlatformTransactionManager transactionManager) {
return new StepBuilder("deleteMemberStep", jobRepository).<Member, Member>chunk(chunkSize,
transactionManager).reader(customReader()).writer(deleteMemberWriter()).build();
}


@Bean
@StepScope
public CustomReader customReader() {
return new CustomReader(entityManagerFactory, chunkSize);
}

@Bean
@StepScope
public ItemWriter<Member> deleteMemberWriter() {
return items -> {
if (items != null && !items.isEmpty()) {
items.forEach(member -> memberRepository.deleteById(member.getMemberId()));
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.programmers.signalbuddy.domain.member.batch;

import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

@Configuration
@EnableScheduling
@RequiredArgsConstructor
public class Scheduler {

private final JobLauncher jobLauncher;
private final Job deleteMemberJob;

@Scheduled(cron = "0 59 23 * * ?")
public void runJob() throws Exception {

JobParameters params = new JobParametersBuilder()
.toJobParameters();
jobLauncher.run(deleteMemberJob, params);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ private void findDatabaseTableNames() {
private void truncate() {
setForeignKeyCheck(OFF);
for (String tableName : tableNames) {
if (tableName.startsWith("BATCH")) {
continue;
}
entityManager.createNativeQuery(String.format("TRUNCATE TABLE %s", tableName)).executeUpdate();
}
setForeignKeyCheck(ON);
Expand Down
7 changes: 7 additions & 0 deletions src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ spring:
show_sql: true
format_sql: true # 이쁘게 보기
dialect: org.hibernate.dialect.MariaDBDialect
open-in-view: false

batch:
jdbc:
initialize-schema: always
job:
enabled: false

logging:
level:
Expand Down
2 changes: 1 addition & 1 deletion submodule
Loading