[์ฐธ๊ณ ] '๋ฐฑ๊ฒฌ๋ถ์ฌ์ผํ - ์คํ๋ง ๋ถํธ ์ผํ๋ชฐ ํ๋ก์ ํธ 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());
}
}
ํ ์คํธ ๊ฒฐ๊ณผ๋ ์ฑ๊ณต!
'๐ Project' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[CORS] CORS๋? CORS ์๋ฌ ํด๊ฒฐ! (0) | 2024.06.30 |
---|---|
[MSA] MSA๋? ์ด ์ ๋ฆฌ (0) | 2024.06.30 |
[Spring boot] (์๋ธ๋ฆฌํ์ ํด๋ก ์ฝ๋ฉ) + MySQL, ํ์ ๊ฐ์ ๊ตฌํ(2) (0) | 2023.07.15 |