본문 바로가기

개발

[스프링부트] 마케팅 수신 동의 멤버 조회, @Cache-

[선택 약관 수신 동의]
- 마케팅 수신 동의와 시스템 수신 동의의 변경(수신O → 수신X or 수신X → 수신O)은 DB에 남아야한다.
- 알림 구현 시 필요한 마케팅 수신 동의 멤버 조회의 기능 최적화

 

1) 마케팅 수신 동의 여부 추가 

마케팅 수신 동의 테이블

: 수신 동의와 수신 철회의 날짜값을 다른 컬럼으로 설정할까 고민했지만 이 후에 멤버의 최신 MarketingConsent를 가지고 오는 로직에서 복잡성이 증가할 것 같아 하나의 컬럼으로 설정하였다.

@NoArgsConstructor
@Getter
@Entity
@Table(name = "marketing_consent")
public class MarketingConsent {

    @Id
    @Column(name = "marketing_consent_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @JsonIgnore
    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

    @Column(name = "is_agreed", nullable = false)
    private Boolean isAgreed; // 동의 여부를 나타내는 필드
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate date;

    @Builder
    public MarketingConsent(Member member, Boolean isAgreed, LocalDate date) {
        this.member = member;
        this.isAgreed = isAgreed;
        this.date = date;
    }
}

 

 

회원가입 Request에 마케팅 수신동의, 시스템 수신동의 여부를 추가

private Boolean marketingConsent; // 마케팅 수신 동의
private Boolean systemConsent;    // 시스템 알림 동의

 

Postman 테스트 

: 회원가입 시 마케팅 수신 동의, 시스템 수신 동의가 제대로 이루어지는지

 


2) @Cache-를 이용한 마케팅 수신 동의 멤버 리스트 조회 

Admin: 마케팅 수신 동의한 멤버 리스트를 조회하는 기능

Member: 회원가입 또는 마케팅 수신 동의 변경 기능

마케팅 수신 동의한 멤버 리스트를 조회하면 member_id 리스트를 캐시에서 조회한다.
회원가입 또는 User가 마케팅 수신 동의 여부를 변경했을 때 캐시는 무효화된다.
캐시를 사용하는 기능이 하나 뿐이기 때문에 기존의 redis를 이어서 사용한다. 

(해당 member_id를 가지고 알림을 전송할 때 해당 멤버의 FCM 토큰을 가져온다.)
(멤버 객체에 FCM 토큰 컬럼 생성 필요, FCM 토큰, 로그인 시 갱신, 로그아웃 시 변경X, 회원탈퇴 시 삭제 → 이 후에 다룸)

 

AdminService

: @Cacheable을 통해 캐시에 해당 데이터가 있다면 가져오고, 없다면 JPQL을 통해 수신 동의한 멤버(member_id) 리스트를 가져오는 로직

@Cacheable(value = "agreedMembersCache")
    public List<Long> findAllAgreedMember(){
        List<Long> agreedMember = marketingConsentRepository.findLatestAgreedMembers();
        return agreedMember;
    }

 

Repository

: MarketingConsent 중 각 멤버에 대해 가장 최신 데이터의 isAgreed가 true인 멤버 리스트를 조회

@Repository
public interface MarketingConsentRepository extends JpaRepository<MarketingConsent, Long> {

    @Query("SELECT mc1.member.id FROM MarketingConsent mc1 WHERE mc1.isAgreed = true AND mc1.date = (" +
            "  SELECT MAX(mc2.date) FROM MarketingConsent mc2 " +
            "  WHERE mc2.member = mc1.member)")
    List<Long> findLatestAgreedMembers();
}

 

 

MemberService

: 멤버 회원가입과 마케팅 수신동의 여부 변경 시 사용되는 로직으로 @CacheEvict를 사용하여 캐시를 무효화한다.

@CacheEvict(value = "agreedMembersCache", allEntries = true)
    public Long saveMarketingConsent(Member member, Boolean isAgreed) {
        marketingConsentRepository.save(
                MarketingConsent.builder()
                        .member(member)
                        .isAgreed(isAgreed)
                        .date(LocalDate.now())
                        .build()
        );
        return member.getId();
    }

 

 

 

테스트

1. admin을 통해 마케팅 수신 동의 멤버 리스트 조회 후 캐시 데이터 확인

 

2. 회원가입을 통해 캐시 무효화 후 캐시 데이터 확인

 

3.  admin을 통해 다시 조회 후 캐시 데이터 확인

 

4. 마케팅 수신 여부 변경 Controller를 통해 변경 후 캐시 데이터 확인

 

→ 모두 정상적으로 동작!!