[참고] '백견불여일타 - 스프링 부트 쇼핑몰 프로젝트 with JPA' 책을 참고하여 작성된 코드입니다!
https://product.kyobobook.co.kr/detail/S000001624717
1. 버전
spring boot 2.7.13
java 11
gradle
IntelliJ IDEA
2. 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-security'
runtimeOnly 'com.mysql:mysql-connector-j'
3. ERD
자유 게시판만 추가했지만 나머지 게시판도 크게 다른 점은 없음
(주제는 에브리타임 클론코딩이지만 세부적인 내용은 능력 부족으로ㅠ 약간 수정될 것 같다)
4. MySQL 연동
① 스키마 생성
② application.properties - MySQL 정보 입력
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/everytime?serverTimezone=UTC
spring.datasource.username=###
spring.datasource.password=###
spring.jpa.hibernate.ddl-auto=update
두번째 datasource.url 부분에 everytime은 본인이 설정한 스키마 이름으로 변경하면 되고, username과 password도 본인 정보에 맞게 수정하면 된다.
5. 스프링 시큐리티 설정
@Configuration
@EnableWebSecurity // Spring Security 설정
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
URL에 따른 인증 및 인가 추가는 추후 진행 예정
6. dto 생성
package com.example.everytime.DTO;
import lombok.*;
@Getter @Setter
public class UserDto {
private String userId;
private String userPwd;
private String userUniv;
private String userEmail;
}
7. entity 생성
package com.example.everytime.constant;
public enum Role {
USER,ADMIN
}
package com.example.everytime.entity;
import com.example.everytime.DTO.UserDto;
import com.example.everytime.constant.Role;
import lombok.*;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.persistence.*;
@Getter @Setter
@Entity
@Table(name = "user")
@ToString
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false, length = 50, unique = true)
private String userId;
@Column(nullable = false, length = 50)
private String userPwd;
@Column(nullable = false)
private String userUniv;
@Column(nullable = false, length = 50, unique = true)
private String userEmail;
@Enumerated(EnumType.STRING)
private Role role;
public static User createUser(UserDto userDto, PasswordEncoder passwordEncoder) {
User user = new User();
user.setUserId(userDto.getUserId());
user.setUserEmail(userDto.getUserEmail());
user.setUserUniv(userDto.getUserUniv());
String password = passwordEncoder.encode(userDto.getUserPwd());
user.setUserPwd(password);
user.setRole(Role.USER);
return user;
}
}
처음이라 책의 예제와 최대한 유사하게 구현하려고 id와 role이 추가되었는데 추후 앞에 설계한 erd에 맞춰 수정할 예정 (본 프로젝트에서는 관리자 버전을 따로 만들지 않을거라 role도 필요없지 않을까 싶다)
@Table(name = "") : "" 안에 적힌 이름으로 MySQL table 생성
@Id : 테이블 기본키 설정
@GeneratedValue : 자동으로 값 증가
@Column : 테이블 열 설정
createUser 함수 : 매개변수로 넘겨받은 dto를 entity로 변경, 비밀번호는 암호화해서 db에 저장
8. repository 생성
package com.example.everytime.repository;
import com.example.everytime.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByUserId(String userId);
}
기본적으로 JpaRepository를 상속받고, 아이디가 중복되면 안되기 때문에 입력한 아이디로 이미 가입한 회원이 있는지 확인하기 위해 findByUserId를 추가했다
9. service 생성
package com.example.everytime.service;
import com.example.everytime.entity.User;
import com.example.everytime.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
@Service
@Transactional
public class UserService {
private final UserRepository userRepository;
public User saveUser(User user) {
validateDuplicateUser(user);
return userRepository.save(user);
}
private void validateDuplicateUser(User user) {
User findUser = userRepository.findByUserId(user.getUserId());
if(findUser != null) {
throw new IllegalStateException("이미 가입된 회원입니다.");
}
}
}
@RequiredArgsConstructor : final이나 @NonNull이 붙은 필드에 생성자를 생성해준다. 빈에 생성자가 1개이고 생성자의 파라미터 타입이 빈으로 등록이 가능하다면 @Autowired 어노테이션 없이 의존성 주입이 가능하다.
10. test 작성
package com.example.everytime.service;
import com.example.everytime.DTO.UserDto;
import com.example.everytime.entity.User;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.annotation.Transactional;
@SpringBootTest
@Transactional
@TestPropertySource(locations = "classpath:application-test.properties")
public class UserServiceTest {
@Autowired
UserService userService;
@Autowired
PasswordEncoder passwordEncoder;
public User createUser() {
UserDto userDto = new UserDto();
userDto.setUserId("kim1111");
userDto.setUserEmail("abcdefg@naver.com");
userDto.setUserUniv("**대학교");
userDto.setUserPwd("kim1111");
return User.createUser(userDto, passwordEncoder);
}
@Test
@DisplayName("회원가입 테스트")
public void saveUserTest() {
User user = createUser();
User savedUser = userService.saveUser(user);
Assertions.assertEquals(user.getId(), savedUser.getId());
}
}
테스트 결과는 성공!
'프로젝트 내용 정리 > 개인 프로젝트' 카테고리의 다른 글
[Spring boot] (에브리타임 클론코딩) + MySQL, 회원 가입 구현(2) (0) | 2023.07.15 |
---|