1-8 회원가입,Login 하기

회원가입,Login
홍윤's avatar
Aug 21, 2024
1-8 회원가입,Login 하기

1.user 패키지

notion image
  • User 패키지에 UserController, UserRepository, UserReuest 클래스 파일 만들기
 

2. User

package shop.mtcoding.blog.user; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.hibernate.annotations.CreationTimestamp; import java.sql.Timestamp; @Getter @Setter @Table(name= "user_tb") @NoArgsConstructor @Entity public class User { //비정형 데이터는 //N쪽에 포린키 가 있어야 한다. //명사들 생각하다가 둘의 관계를 보다가 동사,명사가 된다. //N:N 이면 무조건 중간에 동사가 나온다. @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(unique = true , nullable = false) private String username; // 아이디 @Column(nullable = false) private String password; @Column(nullable = false) private String email; @CreationTimestamp // 하이버네이트의 도움을 받으면 자동으로 시간이 등록된다. private Timestamp createdAt; @Builder public User(Integer id, String username, String password, String email, Timestamp createdAt) { this.id = id; this.username = username; this.password = password; this.email = email; this.createdAt = createdAt; }
💡
@CreationTimestamp // 하이버네이트의 도움을 받으면 자동으로 시간이 등록된다. private Timestamp createdAt;
 

3. UserController

1. 회원가입

package shop.mtcoding.blog.user; import jakarta.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @Controller public class UserController { private final UserRepository userRepository; private final HttpSession session; public UserController(UserRepository userRepository, HttpSession session) { this.userRepository = userRepository; this.session = session; } //회원가입 하고 난 후 @PostMapping("/join") public String join(UserRequest.joinDTO joinDTO) { //insert 하는 모든 것들은 toEntitiy로 하면 된다. userRepository.save(joinDTO.toEntity()); return "redirect:/login-form"; }
  • ‘UserRequest.joinDTO’ 는 메소드의 매개변수인 ‘joinDTO’는 사용자가 폼에서 입력한 데이터를 담고 있는 객체이다. DTO(Data Transfer Object)는 데이터를 전송을 위한 객체로, 주로 요청이나 응답 시 데이터 구조를 정의하는데 사용한다.
  • ‘joinDTO.toEntitiy()’ 는 ‘joinDTO’ 객체를 ‘User’ 엔티티 객체로 변환하고 ‘toEntity()’ 메소드는 DTO를 엔티티로 변환하는 역할을 한다. 엔티티는 데이터베이스 테이블과 매핑된 객체로 ‘joinDTO’에 담긴 데이터를 ‘User’엔티티로 변화하여 데이터베이스에 저장이 가능하다.
  • ‘userRepository.save()’ 이 부분에서 변환된 ‘User’ 엔티티 객체를 데이터베이스에 저장한다.

2.로그인

@PostMapping("/login") public String login(UserRequest.loginDTO loginDTO) { User sessionUser = userRepository.findByUsernameAndPassword(loginDTO.getUsername(),loginDTO.getPassword()); session.setAttribute("sessionUser", sessionUser); return "redirect:/board"; }
  • ‘UserRequest.loginDTO’ 매개변수는 사용자가 로그인 폼에서 입력한 데이터를 담고 있는 객체이다.
  • ‘userRepository.findByUsernameAndPassword(..): 데이터베이스에서 사용자 정보를 조회하는 메소드 호출이다. 데이터베이스에서 ‘username’, ’password’가 모두 일치하는 사용자를 검색한다. 만약 일치하는 사용자가 있다면 해당 ‘User’ 엔티티가 반환되고 그렇지 않으면 ‘null’이 반환된다.
  • ‘sessionUser’는 데이터베이스에서 조회된 사용자 객체를 나타내고있다. 로그인 정보가 맞다면 ‘sessionUser’에는 사용자의 정보가 담긴 ‘User’객체를 저장한다.
  • ‘session.setAttribute(…): 이 코드는 현재 사용자의 세션에 데이터를 저장한다.

3.UserRepository

 

1. 회원정보 조회

package shop.mtcoding.blog.user; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import jakarta.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.sql.Timestamp; import java.time.LocalDateTime; @Repository public class UserRepository { @Autowired private EntityManager em; public User findByUsernameAndPassword(String username, String password) { Query query = em.createQuery("select u from User u where u.username=:username and u.password=:password", User.class); query.setParameter("username", username); query.setParameter("password", password); User user = (User) query.getSingleResult(); return user; }
  • ‘public User findByUsernameAndPassword(String username, String password) 는 주어진 ‘username’과 ‘password’ 에 해당하는 사용자를 데이터베이스에서 찾아 반환한다. ‘User’ 메서드는 ‘User’ 엔티티 객체를 반환한다. 사용자를 찾지 못 하면 예외가 발생한다.
  • Query query = em.createQuery(): ‘EntityManger’의 메소드로 , JPQL 쿼리를 생성한다. JPQL은 엔티티 객체를 대상으로 하는 쿼리 언어다. 엔티티 객체를 기반으로 작동한다.
  • "select u from User u where u.username=:username and u.password=:password", User.class는 JPQL쿼리이다. ‘u’는 ‘User’ 엔티티의 별칭이다. User.classs는 쿼리결과를 ‘User’ 타입으로 매핑하기 위한 정보다.
  • User user = (User) query.getSingleResult(); 쿼리를 실행하여 정확히 하나의 결과를 반환한다. 쿼리 실행 결과로 반환된 ‘User’객체를 ‘user’변수에 저장합니다 이 메서드는 쿼리의 결과가 없거나 여러 개의 결과가 반환될 경우 예외를 발생시킵니다.
💡
  • 예외: javax.persistence.NoResultException (결과가 없을 때)
  • 예외: javax.persistence.NonUniqueResultException (여러 결과가 있을 때)
 

2. 회원가입 수행

@Transactional // 비영속 객체를 영속성 컨텍스트에 잠깐 스치면 바로 insert 해준다. public void save(User user) { System.out.println("담기기전 :" + user.getId()); em.persist(user); System.out.println("담기기후 :" + user.getId()); }
💡
영속성 컨텍스트(Persistence Context)는 JPA(Java Persistence API)에서 중요한 개념으로, 애플리케이션과 데이터베이스 사이의 데이터 상태를 관리하는 메커니즘입니다. JPA는 객체와 데이터베이스 간의 매핑을 처리하며, 영속성 컨텍스트는 이 과정에서 객체의 상태를 관리합니다.

영속성 컨텍스트 요약

  1. 개념:
      • 영속성 컨텍스트는 엔티티(Entity) 객체들을 관리하는 일종의 "저장소"입니다.
      • 엔티티 객체들이 영속성 컨텍스트에 포함되면 "영속 상태"가 됩니다.
      • 영속성 컨텍스트는 엔티티의 생명 주기를 관리하고, 데이터베이스와의 동기화를 담당합니다.
  1. 상태 관리:
      • 비영속 (Transient): 영속성 컨텍스트와 관계없는 상태로, 데이터베이스에 저장되지 않은 상태입니다.
      • 영속 (Persistent): 영속성 컨텍스트에 의해 관리되는 상태로, 데이터베이스에 저장되거나 저장될 수 있는 상태입니다.
      • 준영속 (Detached): 한때 영속 상태였지만, 현재는 영속성 컨텍스트에 의해 관리되지 않는 상태입니다.
      • 삭제 (Removed): 삭제될 예정인 상태로, 영속성 컨텍스트에 의해 관리되지만, 트랜잭션이 커밋되면 데이터베이스에서 삭제됩니다.

요약

영속성 컨텍스트는 엔티티 객체를 관리하고, 데이터베이스와의 동기화 작업을 수행하는 JPA의 핵심 개념입니다. 이 컨텍스트는 엔티티의 상태를 관리하고, 성능 최적화, 상태 변경 감지, 동일성 보장 등을 통해 데이터 일관성을 유지합니다.
 
  • 비영속 상태의 ‘User’ 객체가 메소드의 매개변수로 전달된다.
  • ‘em.persist(user)’ 를 호출하여 ‘User’ 객체를 영속성 컨텍스트에 포함시킨다. 이 시점에서 객체의 ‘id’가 설정될 수 있고, 트랜잭션이 커밋될 때 ‘INSERT’ 쿼리가 데이터베이스에서 실행된다.
  • 이 메소드는 비영속 상태의 ‘User’ 객체를 영속 상태로 전환하여, 데이터베이스에 저장하는 작업을 수행합니다
  • ‘persist'메서드를 통해 영속성 컨텍스트에 포함된 객체는 이후 데이터베이스에 저장됩니다.

 

4. UserRequest(DTO)

package shop.mtcoding.blog.user; import lombok.Data; public class UserRequest { @Data public static class joinDTO{ private String username; private String password; private String email; //DTO를 -> UserObject로 바꿔준다. public User toEntity(){ return User.builder().username(username).password(password).email(email).build(); } } @Data public static class loginDTO{ private String username; private String password; }
 
  • ‘joinDTO’ 클래스는 사용자의 회원가입 요청에서 사용될 데이터를 담는 역할을 합니다.
  • ‘public User toEntity()’는 ‘joinDTO 객체를 ‘User’엔티티로 변환합니다. 회원가입 폼에서 입력된 데이터를 데이터베이스에 저장하기 위해 ‘User’ 객체로 변환하는 것이 필요하기 때문에 이 메소드가 사용됩니다.
  • ‘User.builder()’: ‘User’ 엔티티를 생성하는 빌더 패턴을 사용한다. 이 패턴은 객체 생성과 유연성과 가독성을 높이기 위해 사용된다. ‘build()’ 설정된 필드를 기반으로 ‘User’객체를 생성하고 반환합니다
 
 
Share article

Uni