1. Dependency
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'com.mysql:mysql-connector-j'2. Applications.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://[USERIP]:3306/[USERTABLE]?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true spring.datasource.username=[MYSQLNAME] spring.datasource.password=[MYSQLPASSWORD]JPA에서는 DB와 클라이언트의 요청을 연결해주는 역할을 하는데, SQL구문을 작성하지 않아도 기본적인 구문을 제공한다.
또한, 메소드명을 통해서 SQL을 정의할 수 있게 되어있다는 점에서 편리하다는 장점이 있다.
결론적으로, 사용자가 정의한 Class와 DB의 Table을 Mapping해주는 역할을 한다고 보면 된다.
JPA는 Class - Service - Repository - DB 간의 연결구조를 이루고 있다.
즉, 회원가입 및 로그인과 관련된 JPA를 구성하려면 Class인 UserEntity를 구성하고, 이를 통해 DB에 요청을 할 수 있는 Repository와 둘을 연결하는 Service단을 구성하면 된다.
1. UserEntity(Class)
@Entity // Setter와 Getter는 Lombok에 있는 어노테이션으로 getter와 setter를 자동적으로 매핑시키는 역할을 한다. @Setter @Getter public class UserEntity { // DB에 저장할 때 각 User를 구분하기 위한 id, IDENTITY로 값을 생성하면, 1부터 증가시키며 ID를 자동으로 생성해준다. @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 로그인 ID >> 이는 겹치지 않는 값을 갖도록 해야하므로 UNIQUE 처리를 함 @Column(unique = true) private String username; // 나머지 비밀번호와 권한을 저장하는 변수 private String password; private String role; }2. JoinService(Service)
@Service public class JoinService{ private final UserRepository userRepository; private final BCryptPasswordEncoder bCryptPasswordEncoder; public JoinService(UserRepository userRepository, BCryptPasswordEncoder bCryptPasswordEncoder) { this.userRepository = userRepository; this.bCryptPasswordEncoder = bCryptPasswordEncoder; } public void joinProcess(JoinDTO joinDTO) { // DB 검증 - 만약 기존에 존재하는 ID라면 가입시키지 않음 boolean isUserExist = userRepository.existsByUsername(joinDTO.getUsername()); if(isUserExist) { return; } // DTO -> Entity UserEntity userData = new UserEntity(); // WAS에서는 주로 데이터를 전달만 하는 DTO를 구성하고 이를 Entity로 변환하여 DB에 저장함 userData.setUsername(joinDTO.getUsername()); // 비밀번호는 BCryptPasswordEncoder를 통해서 비밀번호를 암호화함 userData.setPassword(bCryptPasswordEncoder.encode(joinDTO.getPassword())); userData.setRole("ROLE_USER"); // repository의 save 메소드를 호출하여 DB에 저장함 userRepository.save(userData); } }3. JoinRepository(Repository)
public interface UserRepository extends JpaRepository<UserEntity, Long> { // UserEntity에 대한 Repository임을 명시 boolean existsByUsername(String Username); UserEntity findByUsername(String username); }
Class와 DB간의 연결을 완료한 경우 해당 간의 요청을 전달하는 메소드들을 구현해주면 된다.
먼저 View단에서 URL을 요청하여 값을 전달하면 해당 값들을 DTO로 받아서 Service단으로 전달한다.
그리고, Entity로 변환하여 Repository로 전달한 후 DB에 저장하는 과정을 거치면 된다.
간단하게 모식도로 나타내면 다음과 같다.
1. View
<!--join.mustache--> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form action="/joinProc" method="post" name="joinForm"> <input type="text" name="username" placeholder="username"/> <input type="password" name="password" placeholder="password"/> <input type="hidden" name="_csrf" value="{{_csrf.token}}"/> <!--csrf를 enable해놓게 되면 get method 이외에는 모두 csrf token을 통해 서버에 인증하여야 한다.--> <input type="submit" value="login"/> </form> </body> </html>2. Controller
// JoinController.java @Controller public class JoinController { private final JoinService joinService; public JoinController(JoinService joinService) { this.joinService = joinService; } // join view페이지로 연결하는 Mapping @GetMapping("/join") public String joinPage() { return "join"; } // join View에서 데이터를 전달했을 때 joinProcess를 호출하는 메소드 @PostMapping("/joinProc") public String joinProcess(JoinDTO joinDTO) { joinService.joinProcess(joinDTO); // joinService의 joinProcess를 호출하여 DTO를 Entity로 변환하고, // 이를 Repository를 통해 DB에 등록 후 login 화면으로 리다이렉트함 return "redirect:/login"; } }
1) 회원가입 View
![]()
2) 회원가입 결과 DB
![]()