학습 목표 JPA를 활용하여 회원가입 기능을 구현할 수 있다.
package com.tenco.blog_v1.user;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
@Repository // IoC
public class UserRepository {
private final EntityManager em;
/**
* 사용자 저장 메서드 (JPA API 사용)
* @param user
* @return 저장된 사용자 엔티티
*/
@Transactional
public User save(User user) {
// JPQL 은 INSERT 구문을 직접 지원하지 않습니다.
em.persist(user); // 영속화
return user;
}
/**
* 사용자 이름과 비밀번호로 사용자 조회
* @param username
* @param password
* @return 조회된 User 엔티티, null
*/
public User findByUsernameAndPassword(String username, String password) {
TypedQuery<User> jpql =
em.createQuery("SELECT u FROM User u WHERE u.username = :username AND u.password = :password", User.class);
jpql.setParameter("username", username);
jpql.setParameter("password", password);
return jpql.getSingleResult();
}
}
JPQL은 INSERT 문을 직접 지원하지 않습니다. 따라서 새로운 엔티티를 데이터베이스에 저장하려면 EntityManager의 persist 메서드를 사용해야 합니다. 만약 INSERT와 유사한 작업이 필요하다면 Native Query를 사용할 수 있습니다. 그러나 일반적인 경우에는 persist 메서드를 사용하는 것이 권장됩니다.
Native Query 사용 예시
@Transactional
public User saveV2(String username, String password, String email){
Query q1 = em.createNativeQuery("insert into user_tb(username, password, email, created_at) values(?, ?, ?, now())");
q1.setParameter(1, username);
q1.setParameter(2, password);
q1.setParameter(3, email);
q1.executeUpdate();
Query q2 = em.createNativeQuery("select * from user_tb where id = (select max(id) from user_tb)", User.class);
User user = (User) q2.getSingleResult();
return user;
}
JoinDTO 에 User 엔티티 변환 메서드 추가
package com.tenco.blog_v1.user;
import lombok.Data;
@Data
public class UserDTO {
// 정적 내부 클래로 모우자
@Data
public static class LoginDTO {
private String username;
private String password;
}
// 정적 내부 클래로 모우자
@Data
public static class JoinDTO {
private String username;
private String password;
private String email;
public User toEntity() {
return User.builder()
.username(username)
.password(password)
.email(email)
.build();
}
}
}
UserController 코드 추가
@PostMapping("/join")
public String join(@ModelAttribute(name = "joinDTO") UserDTO.JoinDTO reqDto) {
userRepository.save(reqDto.toEntity());
return "redirect:/login-form";
}
user/join-from.mustache
{{> layout/header}}
<main class="container p-5 content">
<div class="card">
<div class="card-header"><b>{{name}}</b></div>
<div class="card-body">
<form action="/join" method="post" enctype="application/x-www-form-urlencoded">
<div class="mb-3">
<input type="text" class="form-control" placeholder="enter username" name="username">
</div>
<div class="mb-3">
<input type="password" class="form-control" placeholder="enter password" name="password">
</div>
<div class="mb-3">
<input type="email" class="form-control" placeholder="enter email" name="email">
</div>
<button type="submit" class="btn btn-primary form-control">회원가입</button>
</form>
</div>
</div>
</main>
{{> layout/footer}}
UserRepository
/**
* 사용자 저장 메서드 (JPA API 사용)
* @param user
* @return 저장된 사용자 엔티티
*/
@Transactional
public User save(User user) {
// JPQL 은 INSERT 구문을 직접 지원하지 않습니다.
em.persist(user); // 영속화
return user;
}
'Spring boot' 카테고리의 다른 글
@SessionAttribute 와 HttpSession을 멤버 필드로 주입 받는 것의 문제점 (0) | 2024.10.18 |
---|---|
회원 정보 수정 (0) | 2024.10.10 |
게시글 수정 하기 (2) | 2024.10.10 |
게시글 삭제 (0) | 2024.10.08 |
게시글 쓰기 (0) | 2024.10.08 |