본문 바로가기
Spring

[Spring] 로그인 구현 1 - 회원 엔티티, Mapper, Repository 구현

by Bhinney 2022. 12. 20.

메인 프로젝트를 하면서 REST API로 로그인을 구현해보았다.

해당 부분을 기억하기 위해 이 글을 작성하였다.

이 포스팅은 프로젝트 과정에서 흐름을 기억하기 위해 작성한 것으로, 기본 흐름의 틀정도라고 생각하면 좋을 듯 하다.

해당 포스팅의 코드는 아래의 깃헙 주소에서도 확인 가능.

 

GitHub - Bhinney/Study: ✨ 공부하면서 기록하는 공간 ✨

✨ 공부하면서 기록하는 공간 ✨. Contribute to Bhinney/Study development by creating an account on GitHub.

github.com


로그인 구현인데 회원 로직 구현인 이유?

: 회원 기본 로직이 구현 되어야 로그인 구현이 가능하기 때문


1️⃣ 공통의 Member 엔티티 구현

  • 공통의 회원 클래스인 Member 엔티티 구현
  • 메인 프로젝트에서 회원을 소비자와 생산자로 나누어 관리
  • 공통의 회원 클래스를 두고, 소비자와 생산자를 나누었음.
@Getter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Member {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long memberId;

   @Column(length = 45, nullable = false)
   private String name;

   @Column(length = 45, nullable = false, unique = true)
   private String email;

   @Column(nullable = false)
   private String password;

   @Column(length = 50, nullable = false)
   private String phone;

   @Column(length = 100, nullable = false)
   private String address;

   /* 소셜 로그인 아이디 추가 */
   @Column
   private String socialId;

   /* 소셜 로그인을 추가하면서 해당 판별을 위한 프로바이더 타입 추가 */
   @Enumerated(EnumType.STRING)
   private ProviderType providerType;

   /* Authority 로 일일히 확인하기 어려우니 컬럼 추가 */
   @Column
   private String role;

   /* security 이용하여 역할 추가 */
   @ElementCollection(fetch = FetchType.EAGER)
   private List<String> roles;

   /* 💜 소비자 - 회원 일대일 연관 관계 : 회원 참조*/
   @OneToOne(mappedBy = "member", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
   private Client client;

   /* 💜소비자 - 회원 연관 관계 편의 메서드 */
   public void setClient(Client client) {
      this.client = client;

      if (client.getMember() != this) {
         client.setMember(this);
      }
   }

   /* 💚 판매자 - 회원 일대일 연관 관계 : 회원 참조 */
   @OneToOne(mappedBy = "member", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
   private Seller seller;

   /* 💚 판매자 - 회원 연관 관계 편의 메서드 */
   public void setSeller(Seller seller) {
      this.seller = seller;

      if (seller.getMember() != this) {
         seller.setMember(this);
      }
   }

   public Member(String name, String email, String password,
      ProviderType providerType, String role, List<String> roles, String socialId) {
      this.name = name;
      this.email = email;
      this.password = password;
      this.providerType = providerType;
      this.role = role;
      this.roles = roles;
      this.socialId = socialId;
   }

   public void setCreateMember(String password, String role, List<String> roles, ProviderType providerType) {
      this.password = password;
      this.role = role;
      this.roles = roles;
      this.providerType = providerType;
   }
}

2️⃣ Seller, Client 엔티티 클래스 구현

  • 나누어 관리할 소비자와 생산자 엔티티 클래스 구현
@Getter
@Entity
@NoArgsConstructor
public class Client {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long clientId;

   /* 💜소비자 - 회원 일대일 연관 관계 : 회원 참조*/
   @OneToOne
   @JoinColumn(name = "member_id")
   private Member member;

   /* 💜소비자 - 회원 연관 관계 편의 메서드 */
   public void setMember(Member member) {
      this.member = member;

      if (member.getClient() != this) {
         member.setClient(this);
      }
   }
}

 

@Getter
@Entity
@NoArgsConstructor
public class Seller {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long sellerId;

   @Column
   private String introduce;

   @Column
   private String imageUrl;

   /* 💚 판매자 - 회원 일대일 연관 관계 : 회원 참조 */
   @OneToOne
   @JoinColumn(name = "member_id")
   private Member member;

   /* 💚 판매자 - 회원 연관 관계 편의 메서드 */
   public void setMember(Member member) {
      this.member = member;

      if (member.getSeller() != this) {
         member.setSeller(this);
      }
   }

   @Builder
   public Seller(Long sellerId, String introduce, String imageUrl) {
      this.sellerId = sellerId;
      this.introduce = introduce;
      this.imageUrl = imageUrl;
   }

}

3️⃣ MemberRepository 구현

  • 회원 CRUD를 위한 Repository 클래스 구현
@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
   Optional<Member> findByEmail(String email);
}

4️⃣ MemberMapper 구현

  • DTO 변환을 위한 Mapper 클래스 구현
@Mapper(componentModel = "spring")
public interface MemberMapper {

   default Member memberPostDtoToMember(MemberDto.Post post) {
      if (post == null) {
         return null;
      }

      Member.MemberBuilder member = Member.builder();

      member.name( post.getName() );
      member.email( post.getEmail() );
      member.password( post.getPassword() );
      member.phone( post.getPhone() );
      member.address( post.getAddress() );
      member.role( post.getRole() );

      return member.build();
   }

   default MemberDto.ClientResponseDto memberToClientResponseDto(Member member) {
      if (member == null) {
         return null;
      }

      MemberDto.ClientResponseDto response =
         MemberDto.ClientResponseDto.builder()
            .memberId(member.getMemberId())
            .clientId(member.getClient().getClientId())
            .email(member.getEmail())
            .name(member.getName())
            .phone(member.getPhone())
            .address(member.getAddress())
            .role(member.getRole())
            .build();

      return response;
   }

   default MemberDto.SellerResponseDto memberToSellerResponseDto(Member member) {
      if (member == null) {
         return null;
      }

      MemberDto.SellerResponseDto response =
         MemberDto.SellerResponseDto.builder()
            .memberId(member.getMemberId())
            .sellerId(member.getSeller().getSellerId())
            .email(member.getEmail())
            .name(member.getName())
            .phone(member.getPhone())
            .address(member.getAddress())
            .role(member.getRole())
            .introduce(member.getSeller().getIntroduce())
            .imageUrl(member.getSeller().getImageUrl())
            .build();

      return response;
   }
}

댓글