스프링부트에서 JPA-MySQL 연동하기 2: 레포지토리 설정

2020. 3. 24. 16:38SpringBoot

목차

1. DAO, Service, Controller 작성

2. REST API를 사용하여 회원가입 기능 구현

이번에는 간단히 CRUD 기능을 사용하기 위해 DAO, Service, Controller를 작성하는 것에 대해 알아보고자 한다.

 

1. DAO, Service, Controller 작성

MyBatis 환경에서 DAO와 동일한 개념이 레포지토리 인터페이스이다. 여기서 JPA의 특징적인 점은 별도의 구현 클래스를 만들지 않고 인터페이스만 정의함으로써 기능을 사용할 수 있다는 것이다.

여기서 보통 Spring Data 모듈에서 제공하는 CrudRepository를 상속한다. 추가적으로 페이징 처리를 할 경우에는 PagingAndSortingRepository를 사용한다.

package com.codepresso.persistence;

import org.springframework.data.repository.CrudRepository;

import com.codepresso.domain.User;

public interface UserRepository extends CrudRepository<User, Long> {

}

 

이렇게 간단한 인터페이스만으로도 데이터 입력이 잘 되는지 보기 위해 간단히 컨트롤러와 서비스를 작성한다.

@RestController
@RequestMapping("/user")
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@PostMapping("/signup")
	public User signUp(@RequestBody User user) {
		User userResult = userService.signUp(user);
		return userResult;
	}

}
@Service
public class UserService {

	@Autowired
	UserRepository userRepo;

	public User signUp(User user) {
		User userResult = userRepo.save(user);
		return userResult;
	}

}

userRepo에 save라는 메소드를 생성하지 않았지만 CrudRepository를 상속하였기 때문에 기본적인 CRUD의 메소드를 바로 사용할 수 있다. ㄹㅇ 편리 ㅎㅎ

CrudRepository가 기본적으로 제공하는 메소드는 다음과 같다.

Modifier and Type Method and Description
long count()

Returns the number of entities available.

void delete(T entity)

Deletes a given entity.

void deleteAll()

Deletes all entities managed by the repository.

void deleteAll(Iterable<? extends T> entities)

Deletes the given entities.

void deleteById(ID id)

Deletes the entity with the given id.

boolean existsById(ID id)

Returns whether an entity with the given id exists.

Iterable<T> findAll()

Returns all instances of the type.

Iterable<T> findAllById(Iterable<ID> ids)

Returns all instances of the type T with the given IDs.

Optional<T> findById(ID id)

Retrieves an entity by its id.

<S extends T>
S
save(S entity)

Saves a given entity.

<S extends T>
Iterable<S>
saveAll(Iterable<S> entities)

Saves all given entities.

그리고 createdAt 변수를 지난번처럼 정의하였더니 DB에 올라가질 않아서 엔티티가 되는 User 클래스는 다음과 같이 수정하였다. 참조

@Getter
@Setter
@ToString
@Entity
public class User {

	@Id
	private String email;
	private String name;
	private String birth;
	private String password;
	@Transient
	private String passwordCheck;
	private String gender;
	private LocalDateTime createdAt;

	@PrePersist
	public void createdAt() {
		this.createdAt = LocalDateTime.now();
	}

}

프로젝트를 실행하고 다음과 같이 포스트맨에서 RequestBody에 필요한 부분들을 입력해주었다.

정상 작동됨을 확인하였다.

 

2. REST API를 사용하여 회원가입 기능 구현

이메일 중복 체크와 비밀번호 확인을 할 수 있는 회원가입 기능을 구현하고자 한다.

@RestController
@RequestMapping("/user")
public class UserController {

	@Autowired
	private UserService userService;
	
	@PostMapping("/signup")
	public ResponseVO signUp(@RequestBody User user) throws Exception {
		
		int emailResult = userService.checkEmail(user);
		boolean pwResult = userService.checkPw(user);
		
		if (emailResult == 0 && pwResult == true) {
			User userResult = userService.signUp(user);
			ResponseVO result = new ResponseVO();
			result.setCode(HttpStatus.OK);
			result.setMessage("SUCCESS");
			result.setData(userResult);
			return result;
		} else {
			ResponseVO result = new ResponseVO();
			result.setCode(HttpStatus.INTERNAL_SERVER_ERROR);
			result.setMessage("FAIL");
			result.setData(null);
			return result;
		}
	}
    
}
@Service
public class UserService {

	@Autowired
	UserRepository userRepo;
	
	@Autowired
	TokenRepository tokenRepo;

	public int checkEmail(User user) {		
		String email = user.getEmail();
		int emailResult = userRepo.countByEmail(email);
		return emailResult;
	}
	
	public boolean checkPw(User user) {		
		logger.info("user: " + user);
		String password = user.getPassword();
		String passwordCheck = user.getPasswordCheck();
		
		if (password.equals(passwordCheck)) {
			return true;
		} else
			return false;
	}
	
	public User signUp(User user) {
		User userResult = userRepo.save(user);
		return userResult;
	}
    
}
@Repository
public interface UserRepository extends CrudRepository<User, String> {
	
	public int countByEmail(String email);
    
}

눈여겨 볼 메소드는

public int countByEmail(String email);

이다.

MyBatis를 사용했으면 매퍼 파일에

<select id="checkEmail" resultType="int">
	<![CDATA[
		SELECT COUNT(*) FROM user
		WHERE email = #{email};
	]]>
</select>

다음과 같이 적었어야 하지만 UserRepository에 count메소드만 선언해주면 위와 같은 쿼리를 실행한다.

보다 복잡한 쿼리는 어떻게 다루어야 하는지는 더 공부가 필요할 듯 하다.