이제 본격적인 회원가입 기능 구현에 들어가보려고 한다.
*application.properties와 build.gradle에 의존성 설정같은것은 생략했다.
Domain패키지
Domain 패키지에서는 DB 테이블과 1:1로 매핑되는 JPA 엔티티로 구성한다.
User DB에는 User, Stack, Position, Organization으로 구성되어 있기 때문에 아래와 같이 코드를 작성하였다.
User.java 소스코드
package ssu.cromi.teamit.domain;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
//유저테이블 도메인
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED) // JPA 용
@AllArgsConstructor
@Data // @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor
@Entity
@Table(name = "users")
public class User {
@Id
@Column(name = "uid", length = 50, nullable = false, updatable = false)
private String uid;
@Column(name = "pw", length = 255, nullable = false)
private String password;
@Column(name = "nick_name", length = 100, nullable = false)
private String nickName;
@Column(name = "email", length = 255, nullable = false)
private String email;
@Column(name = "email_verified", length = 1, nullable = false)
private Boolean emailVerified = false;
@Column(nullable = false)
private Integer birthday;
@Column(nullable = false)
private Long point;
@Column(name = "profile_img", length = 2083)
private String profileImg;
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
@Column(name = "my_score")
private Double myScore;
@Column(name = "roles", length = 50, nullable = false)
private String roles = "ROLE_USER";
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;
// 관계 매핑
@ManyToMany
@JoinTable(
name = "user_organizations",
joinColumns = @JoinColumn(name = "uid"),
inverseJoinColumns = @JoinColumn(name = "organization_id")
)
private Set<Organization> organizations = new HashSet<>();
@ManyToMany
@JoinTable(
name = "user_stacks",
joinColumns = @JoinColumn(name = "uid"),
inverseJoinColumns = @JoinColumn(name = "stack_id")
)
private Set<Stack> stacks = new HashSet<>();
@ManyToMany
@JoinTable(
name = "user_positions",
joinColumns = @JoinColumn(name = "uid"),
inverseJoinColumns = @JoinColumn(name = "position_id")
)
private Set<Position> positions = new HashSet<>();
public User(String uid, String password, String nickName, String email, Integer birthday) {
this.uid = uid;
this.password = password;
this.nickName = nickName;
this.email = email;
this.birthday = birthday;
}
@ToString
public enum RoleEnum {
ROLE_USER,
ROLE_ADMIN
}
}
클래스 선언부
@Entity
이 클래스의 인스턴스(객체)를 데이터베이스의 한 row와 매핑 하겠다는 의미
@Table(name = “users”)
실제 테이블 이름을 users로 지정한다는 의미
Lombok 애노테이선
@Data
자동으로 Getter/Setter, toString, equalsAndHashCode등의 bean과 관련된 모든 재사용 가능한 코드를 생성해줌
@Builder
빌더 패턴을 지원한다는 의미
User u = User.builder()
.uid("Crom")
.nickName("Kiwi")
.build();
@NoArgsConstructor(access = PROTECTED)
파라미터 없는 생성자를 만들되, 외부에서 직접 호출하지 못하도록 protected접근 제한 (JPA가 내부적으로 객체를 생성할 때 필요함)
@AllArgsConstructor
모든 필드를 파라미터로 받는 생성자를 자동 생성
주요 필드와 매핑
@ID
기본 키(PK)역할을 하는 필드
@Comlum
데이터베이스 칼럼 설정(이름, 길이, 널 허용 여부, 수정 가능 여부 등)
연관 관계 매핑
@ManyToMany
N:N 관계 설정하기 위한 애노테이션
@JoinTable
두 테이블을 중간 테이블로 연결
권한 정의
@ToString
public enum RoleEnum {
ROLE_USER,
ROLE_ADMIN
}
ROLE_USER, ROLE_ADMIN 두 가지 역할을 미리 enum 으로 정의
Stack.java 소스코드
package ssu.cromi.teamit.domain;
import jakarta.persistence.*;
import lombok.Data;
import java.util.HashSet;
import java.util.Set;
@Data
@Entity
@Table(name = "stack_table")
public class Stack {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "stack_tag", nullable = false, unique = true)
private String tag;
@Column(name = "stack_icon", length = 2083)
private String icon;
@ManyToMany(mappedBy = "stacks")
private Set<User> users = new HashSet<>();
protected Stack(){}
}
@GeneratedValue(strategy = GenerationType.IDENTITY)
이 필드가 데이터베이스에 저장될 때 JPA가 자동으로 키 값을 생성해주도록 설정 데이터베이스의 AUTO_INCREMENT(MySQL)기능에 맡겨 값이 자동으로 1씩 증가하도록 설정
Position.java
package ssu.cromi.teamit.domain;
import jakarta.persistence.*;
import lombok.Data;
import java.util.HashSet;
import java.util.Set;
@Data
@Entity
@Table(name = "position_table")
public class Position {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "position_tag", nullable = false, unique = true)
private String tag;
@Column(name = "position_icon", length = 2083)
private String icon;
@ManyToMany(mappedBy = "positions")
private Set<User> users = new HashSet<>();
protected Position(){}
}
SignupRequest.java
package ssu.cromi.teamit.DTO.auth;
//회원가입 DTO
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.*;
import lombok.*;
import org.hibernate.validator.constraints.Length;
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class SignupRequest {
@JsonProperty("uid")
@NotBlank(message = "UID 누락됨")
private String uid;
@JsonProperty("nickName")
@NotBlank(message = "닉네임 누락됨")
private String nickName;
@JsonProperty("password")
@ToString.Exclude // pw는 toString, Equals 제외
@EqualsAndHashCode.Exclude
@NotBlank(message = "PW 누락됨")
@Length(min = 8, max=20, message = "최소길이 8, 최대길이 20")// pw 최소, 최대 길이 설정
private String password;
@JsonProperty("email")
@NotBlank(message = "이메일 누락됨")
@Email(message = "유효한 이메일 형식이 아님")
private String email;
@JsonProperty("emailVerified")
private boolean emailVerified;
@JsonProperty("birthDay")
private Integer birthDay;
}
@JsonProperty()
JSON필드 이름과 자바 클래스의 프로퍼티를 매핑해주는 역할
'IT 프로젝트 공모전(백엔드)' 카테고리의 다른 글
| [Spring boot]Spring Security와 JWT를 활용한 로그인 인증 시스템 구현 (2) | 2025.08.15 |
|---|---|
| [Spring boot] 회원가입 기능구현 4(Service, Controller, Security 설정) (0) | 2025.07.23 |
| [Spring boot] 회원가입 기능구현 3(Repository, DTO) (1) | 2025.07.23 |
| [Spring boot] 회원가입 기능구현 1 (설계, 계층, ERD, SQL 스키마) (0) | 2025.07.15 |
| IT 프로젝트 기획 시작 (1) | 2025.06.20 |