Springboot/블로그만들기

[Springboot] 블로그 만들기 (9)_회원가입 insert 테스트

21종 2023. 11. 24. 17:52

테스트용 클래스 생성

파일명 : DummyControllerTest

보통 파라미터 값을 받기 위해서 아래와 같이 RequestParam이라는 어노테이션을 사용해서 받는다. 이때 변수명은 아무렇게 지어도 상관이 없다.

public String join(@RequestParam("키 값") String 변수명) { <- 보통 파라미터값을 받을때

 

 

하지만 Spring에서는 이렇게 하지 않고 변수명과 받아올 키값을 정확히 맞춰주면 이 join함수의 파라미터에 쏙 들어가게 된다. 

public String join(String userName, String password, String email) { //key = value(약속된 규칙)
// http://localhost:8001/blog/dummy/join(요청)
// http의 body에 userName, password, email 데이터를 가지고 (요청)
@PostMapping("/dummy/join")
public String join(String userName, String password, String email) { //key = value(약속된 규칙)
    System.out.println("userName : " + userName);
    System.out.println("password : " + password);
    System.out.println("email : " + email);
    return "회원가입이 완료되었습니다.";
}

postman 어플리케이션을 이용해서 테스트를 해보자

 

userName, password, email 값을 넣고 Send 를 누르면 콘솔에 아래와 같이 잘 전달이 되는것을 볼 수 있다.


이 방법 말고도 스프링에서의 강력한 기능이 하나가 더 있다.

파라미터에 key 값을 넣어주는게 아닌 객체로도 받아줄수 있다. 

물론 User 객체의 변수명과 넘겨받는 파라미터의 키 값이 동일해야 한다.

public String join(User user) { // User obj로 받을 수 있다.
    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("createDate : " + user.getCreateDate());
    return "회원가입이 완료되었습니다.";

}

 

 

하지만 만약에 파라미터 값을 아래와 같이 password2로 User객체의 변수명과 동일하지 않다면 ?

이와 같이 password2는 User객체에 존재하지 않는 변수기 때문에 password 값을  인식하지 못하고  null을 리턴하게 된다.


이제 실제로 테이블에 값을 insert 해보자

 

Repository 생성

경로 : src/main/java/com/lwj/blog/repository/UserRepository.java

package com.lwj.blog.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.lwj.blog.model.User;

// DAO
// 자동으로 bran 등록이 된다.
//-> @Repository 생략 가능하다. 
public interface UserRepository extends JpaRepository<User, Integer>{ 
	// 해당 JpaRepository는 user테이블이 관리하고 이 테이블의 PK는 숫자형이다.
	// 이 JpaRepository는 findAll()이라는 함수를 갖고 있는데 이 함수는 테이블의 모든행을 리턴하는 함수이다.
	// 이 함수는 데이터 CRUD를 처리할 수 있다.

}

 


DummyControllerTest

@Autowired 를 이용해서 Controller에 의존성을 주입하고 CRUD를 하고 싶은 메소드에서 사용하기만 하면 끝이다.

package com.lwj.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.lwj.blog.model.User;
import com.lwj.blog.repository.UserRepository;

@RestController
public class DummyControllerTest {
	
	@Autowired // 의존성 주입(DI)
	private UserRepository userRepository;

	public String join(User user) {
		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("createDate : " + user.getCreateDate());
		
		userRepository.save(user); // 파라미터로 가져온 값이 insert된다. 
		return "회원가입이 완료되었습니다.";
		
	}
}

 

그럼 insert가 잘 되는지 테스트를 해보자

 

MySQL에서 확인 결과 데이터가 잘 들어가는것을 알 수 있다.

근데 Role은 default값으로 "user"를 넣었는데 왜 Null이 들어갈까 ?

콘솔창을 확인해보니 지금 insert 할때 쿼리가 아래와 같이 들어가고 있다.

 

쿼리가 이렇게 되면 당연히 role값으로 null이 들어가게된다.

아래와 같이 쿼리문이 전달돼야 한다.

insert 
into
    User
    (createDate, email, password, userName) #insert 할때 role 값이 없어야한다. 
values
    (?, ?, ?, ?)

 

그럼 어떻게 할까 ? 

--> User 객체에 @DynamicInsert 어노테이션을 붙이면 된다.

@DynamicInsert
public class User {

 

 

확인결과 잘 role 값이 잘 들어가는것을 볼 수 있다.

 

그러나 이것은 좋은방법이 아니다. 

 

User 객체에서 @DynamicInsert 와 @ColumnDefault를 주석처리하자.

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity // User 클래스가 MySQL에 테이블이 생성이 된다. // 이 어노테이션이 가장 가까이 있는게 좋다
//@DynamicInsert // insert시에 null인 필드를 제외시켜준다.
public class User {
	
	@Id // Primary key
	@GeneratedValue(strategy = GenerationType.IDENTITY) 
	private int id;	// 시퀀스, mySQL : auto_increment
	  
	@Column(nullable=false, length = 30)
	private String userName; // 아이디
	
	@Column(nullable=false, length = 100) 
	private String password; // 비밀번호
	
	@Column(nullable=false, length = 50)
	private String email; // 이메일
	
	//@ColumnDefault("'user'")
	private String role; // Enum을 쓰는게 좋다.
	
	@CreationTimestamp
	private Timestamp createDate;

}

 

 

그리고 Insert작업을 수행하는 메소드에가서 User의 role값을 setter 메소드를 이용하여 직접대입한다.

@RestController
public class DummyControllerTest {
	
	@Autowired // 의존성 주입(DI)
	private UserRepository userRepository;

	@PostMapping("/dummy/join")
	public String join(User user) {
		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("createDate : " + user.getCreateDate());
		
		user.setRole("user");
		//user.setRole("user2"); // 개발자가 실수를 할수도있다.  
        
		userRepository.save(user); // 파라미터로 가져온 값이 insert된다. 
		return "회원가입이 완료되었습니다.";
		
	}
}

 

이렇게 코딩을하게되면 개발자가 실수를 할 수 있다. 이것도 그렇게 좋은 방법이 아니다. 즉, 도메인 설정을하자


Enum생성 (도메인 설정)

com/lwj/blog/model 에 enum을 생성해준다. 파일명은 RoleType

 

 

RoleType.java

package com.lwj.blog.model;

public enum RoleType {

	USER, ADMIN // 값으로 USER, ADMIN만 들어갈수 있다는 뜻
}

 

 User.java

기존의 이 코드를

@ColumnDefault("'user'")
private String role;

 

아래와 같이 변경해준다.

@Enumerated(EnumType.STRING) // DB에는 RoleType이라는게 없기 때문에 String이라고 알려줘야한다.
private RoleType role; // ADMIN, USER 만 값이 들어가게된다.

 

Controller

public String join(User user) {
    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("createDate : " + user.getCreateDate());

    // user.setRole("user"); // 이제 role에 값을 직접 String 형으로 대입할 수 없다 
    // -> 개발자가 실수로 이상한 값을 넣는것을 방지할 수 있다.
    user.setRole(RoleType.USER);

    userRepository.save(user); // 파라미터로 가져온 값이 insert된다. 
    return "회원가입이 완료되었습니다.";

}

잘 들어간다.


참고 유튜브 (메타코딩님 강의)

https://youtu.be/FhrkWA9hioU?si=ocTWK9xylNA9-0Lg