회원가입을 위한 insert 테스트
DummyControllerTest.java 작성
실행결과 :
실행결과 :
성공적으로 값이 잘 받아진다.
이제 회원가입을 위한 insert 테스트를 진행해보자
우선 UserRepository를 만들자.
com.cos.blog.repository 패키지를 만들고 그 곳에 Interface인 UserRepository.java 를 만든다.
extends JpaRepository를 한다.
JpaRepository에는 User테이블이 들고 있는 모든 행을 다 리턴하는 findAll() 함수가 있다.
또 PagingAndSortingRepository.class에는 정렬을 하거나 페이징을 해서 받는 등의 함수가 있다.
따라서 이런 함수들을 직접 작성하지 않아도 된다.
extends 했기 때문에 UserRepository가 이제 다 들고있기 때문이다.
UserRepository.java
package com.cos.blog.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.cos.blog.model.User;
// DAO
// 자동으로 bean 등록이 된다.
// @Repository 생략이 가능하다.
public interface UserRepository extends JpaRepository<User, Integer>{
// 해당 JpaRepository는 User테이블을 관리하는 Repository이다.
// 그리고 User테이블의 Primary key는 Integer이다.
}
DummyControllerTest.java
package com.cos.blog.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cos.blog.model.User;
import com.cos.blog.repository.UserRepository;
@RestController // 페이지를 리턴하는 것이 아니므로 RestController
public class DummyControllerTest {
// @Autowired 전에는 null값이다.
// ↓ 의존성 주입 // Autowired로 UserRepository를 메모리에 띄워준다.
@Autowired // UserRepository 타입으로 스프링이 관리하고 있는 객체가 있다면 userRepository로 넣어라
private UserRepository userRepository;
// http://localhost:9090/blog/dummy/join (요청)
// http의 body에 username, password, email 데이터를 가지고 (요청)
@PostMapping("/dummy/join") // 회원가입(insert) 해야하니 PostMapping
public String join(User user) {
// @RequestParam("username") String u 이렇게해도 username이 변수 u에 딱 들어옴
System.out.println("id : "+user.getId());
System.out.println("username : "+user.getUsername());
System.out.println("password : "+user.getPassword());
System.out.println("email : "+user.getEmail());
System.out.println("role : "+user.getRole());
System.out.println("createDate : "+user.getCreateDate());
userRepository.save(user);
return "회원가입이 완료되었습니다.";
}
}
실행결과 :
role빼고는 다 잘 들어온 것을 확인할 수 있다.
그럼 role은 왜 안들어왔을까?
우선, id는 @GeneratedValue(strategy = GenerationType.IDENTITY) 사용으로
auto_increment를 적용시켰었으니 당연히 자동으로 들어온다.
createDate도 @CreationTimestamp 사용으로 데이터가 insert나 update 될 때 시간이 자동으로 입력된다.
이 둘은 userRepository.save(user); 될 때 데이터가 들어가는 것이다.
그런데 role같은 경우는 현재 설정된 Default Value가 user이다.
이 Default Value가 작동하려면 (createDate, email, password, role, username) 값을 넣을 때 작동하는 것이 아니라
(createDate, email, password, username) 를 넣을 때 작동한다!!
(createDate, email, password, role, username)해서 null값을 넣어버리면 그대로 role에 null값이 들어가는 것이다.
그런데 대체 이 role 필드를 어떻게 제외할까?
이 방법은 간단하다.
@DynamicInsert 를 사용하는 것이다. 이는 insert할 때 null인 필드를 제외시켜준다.
따라서 User에 @DynamicInsert를 다음과 같이 import해서 적용시켜주고
실행해보면
이제 성공적으로 Default Value인 user가 적용된 것을 확인할 수 있다.
@DynamicInsert 사용을 통해 insert할 때 null인 필드가 제외되었기 때문이다.
그런데 어노테이션을 덕지덕지 붙이면 결코 좋은 것은 아니기 때문에
User.java에서 @DynamicInsert을 삭제하고, @ColumnDefault("'user'")도 삭제하자
현재 User.java
package com.cos.blog.model;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.DynamicInsert;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder // 빌더 패턴
@Entity // User 클래스가 MySQL에 테이블이 생성된다.
public class User {
@Id // Primary key
@GeneratedValue(strategy = GenerationType.IDENTITY)
// 프로젝트에서 연결된 DB의 넘버링 전략을 따라간다. 즉, MySQL일 경우 auto_increment를 사용한다는 것이다.
private int id; // 시퀀스(오라클), auto_increment로 넘버링(MySQL)
@Column(nullable = false, length = 30) // null이 될 수 없고, 30자 이상이 될 수 없다.
private String username; // 아이디
@Column(nullable = false, length = 100) // 비밀번호 암호화한 해쉬 넣어볼 예정이므로 길게 설정
private String password;
@Column(nullable = false, length = 50)
private String email;
private String role;
// admin, user, manager ...
// 정확히는 Enum을 사용하는 것이 좋다. Enum을 사용하면 어떤 데이터의 도메인(범위)을 만들 수 있다.
// role이 String이므로 adminn과 같은 오타를 낼 수가 있다. Enum을 사용하면 이를 방지할 수 있다.
@CreationTimestamp // 데이터가 insert나 update 될 때 시간이 자동으로 입력된다.
private Timestamp createDate;
}
그리고 DummyControllerTest.java에
user.setRole("user"); 코드를 추가하였다.
enum 사용법
그런데 이렇게 코드를 추가할 때 개발자가 실수로 user가 아니라 userr 같은 오타를 낼 수도 있는데,
이를 방지하는 방법이 있다.
Enum Type 파일을 만들고
User.java 파일에서 private String role; 을 private RoleType role;로 바꿔준다.
그런데, DB는 RoleType이라는 것이 없기 때문에 해당 Enum이 String이라고 DB에 알려주어야한다.
따라서 다음과 같은 어노테이션을 작성한다.
그리고 DummyControllerTest.java 파일에 들어가보면
이렇게 오류가 떠 있을 것이다.
당연히 User.java에서 role의 타입을 String이 아니라 RoleType으로 명시했기 때문에 String이 들어갈 수 없다.
따라서 다음과 같이 코드를 다시 작성한다.
실행결과 :
깔끔하게 값이 전달되었다.
+ 추가
application.yml에 들어가서
ddl-auto를 update로 해준다.
create로 되어있으면 저장할 때 마다 기존 데이터가 다 삭제된다.
학습자료 : https://youtu.be/oOJR2XCagdA
'자바 스프링 > 부트 블로그 JPA 프로젝트' 카테고리의 다른 글
#13 update 테스트 (0) | 2022.05.07 |
---|---|
#12 select 테스트 및 페이징 (0) | 2022.05.06 |
#10 연관관계에 대한 이해 (0) | 2022.05.05 |
#9 JPA와 DB테이블 생성(User, Board, Reply) (0) | 2022.05.05 |
#8 스프링 부트의 yml과 jsp파일 리턴 (0) | 2022.05.04 |