๐Ÿžํ”„๋กœ๊ทธ๋ž˜๋ฐ

[์ •๋ณด] jpa repository ์ฟผ๋ฆฌ๋ฌธ ์ž‘์„ฑ ์‹œ ์ฃผ์˜์ 

TwoIceFish 2023. 3. 12. 23:29

์•„๋ž˜ ์ฝ”๋“œ๋Š” ํšŒ์› ๊ฐ€์ž… ์‹œ ์ด๋ฉ”์ผ ์ฃผ์†Œ์˜ ์ค‘๋ณต์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ JPA Repository ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ž์—ด email์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ v.email = :email ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. String email์„ ๋งคํ•‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ฝœ๋ก (:)์„ email์— ๋ฐ”๋กœ ๋ถ™์—ฌ์„œ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์ง€ํ‚ค์ง€ ์•Š์œผ๋ฉด null Exception์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ์ด๋ฉ”์ผ ์ธ์ฆ์„ ํ†ตํ•œ ํšŒ์›์˜ ์กด์žฌ ๋ฐ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ณ  ๊ฐ€์ž…์— ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง์œผ๋กœ ์˜ˆ๋ฅผ ๋“ ๋‹ค.

@Repository
public interface SignUpRepository extends JpaRepository<MemberEntity, Long> {

    /**
     * ์ฃผ์–ด์ง„ ์ด๋ฉ”์ผ ์ฃผ์†Œ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
     *
     * @param email ์ด๋ฉ”์ผ ์ฃผ์†Œ
     * @return ์ด๋ฉ”์ผ ์ฃผ์†Œ๊ฐ€ ์กด์žฌํ•˜๋ฉด true, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด false
     */
    Boolean existsByEmail(String email);

    /**
     * ์ฃผ์–ด์ง„ ์ด๋ฉ”์ผ ์ฃผ์†Œ์— ํ•ด๋‹นํ•˜๋Š” ํšŒ์› ๊ฐ€์ž… ์ •๋ณด์˜ ์ธ์ฆ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
     *
     * @param email ์ด๋ฉ”์ผ ์ฃผ์†Œ
     * @return ์—…๋ฐ์ดํŠธ๋œ ํ–‰(row)์˜ ์ˆ˜
     */
    @Modifying
    @Transactional
    @Query("UPDATE MemberEntity v SET v.verified = true WHERE v.email = :email")
    int updateVerified(@Param("email") String email);
}

 

@Repository์˜ ๊ฒฐ๊ณผ๊ฐ’์€ @Service์—์„œ ๊ฒฐ๊ณผ ๊ฐ’ int(์˜ํ–ฅ์„ ๋ฐ›์€ ํ–‰ ์ˆ˜)๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์“ฐ์ธ๋‹ค.

/**
 * ์ด๋ฉ”์ผ ์ธ์ฆ์„ ํ†ตํ•ด ํšŒ์›๊ฐ€์ž…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
 * 
 * @param value ์ธ์ฆ ๊ฐ’
 * @return ํšŒ์› ๊ฐ€์ž…ํ•œ ์ด๋ฉ”์ผ ์ฃผ์†Œ ๋˜๋Š” false
 */
public String checkVerification(String value) {
    // ๊ฐ’ ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ
    Optional<VerificationEntity> vEntity = verificationRepository
            .findByVerificationValueAndExpiredAndVerified(value, false, false);
    
    if (vEntity.isPresent()) {
        // ์ธ์ฆ ์™„๋ฃŒ ์ฒ˜๋ฆฌ
        verificationRepository.updateVerified(value);
        
        // ํšŒ์› ๊ฐ€์ž… ์ •๋ณด ์—…๋ฐ์ดํŠธ
        if (1 == signUpRepository.updateVerified(vEntity.get().getEmail())) {
            // ํšŒ์› ๊ฐ€์ž…ํ•œ ์ด๋ฉ”์ผ ์ฃผ์†Œ ๋ฐ˜ํ™˜
            return vEntity.get().getEmail();
        }
    }
    
    // ํšŒ์› ๊ฐ€์ž… ์ •๋ณด๊ฐ€ ์—†๊ฑฐ๋‚˜ ์ด๋ฏธ ์ธ์ฆ๋œ ๊ฒฝ์šฐ false ๋ฐ˜ํ™˜
    return "false";
}

 

@Service์˜ ๊ฒฐ๊ณผ ๊ฐ’์€ @Controller์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์“ฐ์ธ๋‹ค.

/**
 * ์ด๋ฉ”์ผ ์ธ์ฆ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ์ฒ˜๋ฆฌ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
 * 
 * @param value ์ธ์ฆ ๊ฐ’
 * @param model ๋ทฐ์— ์ „๋‹ฌํ•  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ๋ชจ๋ธ
 * @return ๋ทฐ ์ด๋ฆ„
 */
@GetMapping("/verification")
public String verificationAction(String value, Model model) {
    // ์ด๋ฉ”์ผ ์ธ์ฆ ์ฒ˜๋ฆฌ
    String result = verificationService.checkVerification(value);

    // ์ธ์ฆ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ๋ทฐ์— ์ „๋‹ฌํ•  ๋ฐ์ดํ„ฐ ์„ค์ •
    if (!result.equals("false")) {
        // ์ธ์ฆ ์„ฑ๊ณต ๋ฉ”์‹œ์ง€ ์„ค์ •
        model.addAttribute("message", "์ธ์ฆ์ด ์™„๋ฃŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
        model.addAttribute("type", "info");
        
        // ํšŒ์› ์ •๋ณด ์„ค์ •
        model.addAttribute("member", MemberDTO.builder().email(result).build());
    } else {
        // ์ธ์ฆ ์‹คํŒจ ๋ฉ”์‹œ์ง€ ์„ค์ •
        model.addAttribute("message", "์ธ์ฆ์ฝ”๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
        model.addAttribute("type", "warning");
    }
    
    // ํšŒ์› ๊ฐ€์ž… ํŽ˜์ด์ง€๋กœ ์ด๋™
    return "member/sign-in";
}

 

@View(Mustache)์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด message๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค. ์ฃผ๋กœ Alert์ฐฝ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํšŒ์‹ ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ์“ด๋‹ค.

{{#message}}
    <div class="alert alert-{{#type}}{{type}}{{/type}}" role="alert">
        {{message}}
    </div>
{{/message}}

 

@์›น๋ถ€๋ผ์šฐ์ €์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ™•์ธ๋œ๋‹ค.