Spring

[Spring] 스프링부트로 CRUD 구현

pseudocoder_ 2023. 8. 9. 00:58
728x90

스프링부트를 활용해서 기본적인 CRUD를 구현해 보자. 

 

세팅은 아래와 같이 세팅하고 진행했으며 의존성은 간단한 CRUD만 구현할 거라 Spring Web, Lombok을 추가하였다.

 

구성은 기본적인 Layered Architecture(계층화 아키텍처)로 구현하였다. Layered Architecture(계층화 아키텍처) 다른 게시물에서 추후에 다루도록 하겠다! 

 

구성

먼저 영역을 간단하게 Dto, Repository, Service, Controller로 구성하고 패키지를 생성하였다.

 

UserDto

UserDto에 변수를 저장해 주고 필요한 Lombok 어노테이션을 추가해 주자. 변수의 접근제한자는 private이기 때문에 외부에서 변수에 접근하여 값을 불러오고 값을 변경해 주기 위해서는 Lombok의 @Getter와 @Setter가 반드시 필요하다! 생성자 자동 생성을 위한 @NoArgsConstructor와 @AllArgsConstructor도 추가해 주자. @AllArgsConstructor만 추가했다가 POST호출 시 500 Internal Server Error가 떴었다.

package com.example.crud_practice.UserDto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class UserDto {
    private String userId; //유저 아이디
    private String userName; //유저 이름
    private String phoneNumber; //유저 휴대폰 번호
    private String password; //유저 비밀번호
    private String userEmail; //유저 이메일
}

 

Repository

다음은 Repository를 살펴보자.

  1. 레포지토리 어노테이션 입력
  2. 전체 유저 정보를 담기 위한 ArrayList 생성
  3. 유저 정보 CRUD 기능 생성

위의 절차대로 진행하였다!

package com.example.crud_practice.Repository;

import com.example.crud_practice.UserDto.UserDto;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

@Repository // Repository 어노테이션을 사용하여 레포지토리로 정의.
public class UserRepository {
    static public ArrayList<UserDto> users; // 전체의 유저 정보가 담길 ArrayList

    static {
        users = new ArrayList<>(); // 더미 데이터를 추가해보자.
        users.add(new UserDto("gil1234", "홍길동", "010-1234-5678", "1q2w3e4r!", "gildong@mail.com"));
        users.add(new UserDto("chulsoo", "김철수", "010-1414-2323", "asdfasdf", "chulsoo@mail.com"));
    }

    // 유저 정보 추가
    public UserDto insertUser(UserDto user){
        users.add(user);
        System.out.println("유저 정보가 추가되었습니다!");
        return user;
    }

    // 모든 유저 정보 불러오기
    public List<UserDto> getAllUsers(){
        System.out.println("모든 유저 정보를 호출합니다!");
        return users;
    }

    // 유저 정보 아이디로 불러오기
    public UserDto getUserByUserId(String userId){
        return users.stream()
                .filter(userDto -> userDto.getUserId().equals(userId))
                .findAny()
                .orElse(new UserDto("null", "null", "null", "null", "null"));
    }

    // 유저 패스워드 변경하기
    public void updateUserPw(String userId, UserDto user){
        users.stream()
                .filter(userDto -> userDto.getUserId().equals(userId))
                .findAny()
                .orElse(new UserDto("null", "null", "null", "null", "null"))
                .setUserPassword(user.getUserPassword());
    }

    // 유저 정보 삭제하기
    public void deleteUser(String userId){
        users.removeIf(userDto -> userDto.getUserId().equals(userId));
        System.out.println("유저 정보가 삭제되었습니다!");
    }
}

 

Service

다음은 Service를 살펴보자. 사실 크게 어려울 건 없는데, Repository와 마찬가지로 @Service 어노테이션을 달아준다. 계층형 아키텍처에서는 서로 근접한 계층끼리만 통신을 하는 것이 핵심이므로 Repository와 Service 계층과의 연결을 위해 @Autowired 어노테이션을 통해 의존성을 주입해 주었다. 나머지는 Repository의 메서드들을 리턴해주는 메서드를 정의해 주는 것이라 크게 어렵지 않았다. 물론 "간단한" CRUD 구현이기에 이렇게 쉬운 것이다...!

package com.example.crud_practice.Service;

import com.example.crud_practice.Repository.UserRepository;
import com.example.crud_practice.UserDto.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {
    @Autowired // 의존성 주입
    UserRepository userRepository;

    public UserDto insertUser(UserDto user){
        return userRepository.insertUser(user);
    }

    public List<UserDto> getAllUsers(){
        return userRepository.getAllUsers();
    }

    public UserDto getUserByUserId(String userId){
        return userRepository.getUserByUserId(userId);
    }

    public void updateUserPw(String userId, UserDto user){
        userRepository.updateUserPw(userId, user);
    }

    public void deleteUser(String userId){
        userRepository.deleteUser(userId);
    }
}

 

Controller

마지막으로 Controller를 살펴보자.

  1. REST API처리를 돕는 @RestController를 추가하자. @RestController를 추가함으로써 데이터를 RESTful 한 통신을 하며 결과 데이터를 json형식으로 받아올 수 있다.
  2. @RequestMapping("{URI}")을 추가하자. 해당하는 URI이 입력되면 Request가 호출되는 것이다!
  3. @Autowired를 활용하여 이전 계층(Service)과의 의존성을 설정해 준다.
  4. @GetMapping(), @PostMapping(), @PutMapping(), @DeleteMapping()을 각각 필요에 따라 활용하여 CRUD를 구현한다!
    • @PostMapping() 사용 시 @RequestBody를 활용하여 자바 객체와 json 형태의 데이터 사이에 매핑을 해 주는 것을 잊지 말자! @RequestBody를 생략할 경우 Repository의 메서드에서 데이터를 인식하지 못한다.
package com.example.crud_practice.Controller;

import com.example.crud_practice.Service.UserService;
import com.example.crud_practice.UserDto.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/user") // Request를 보내는 URL
public class UserController {
    @Autowired // 의존성 주입
    UserService userService;

    @PostMapping("") // CRUD의 C
    // HTTP 요청 -> 자바 객체 매핑 위해서 @RequestBody 활용
    public UserDto insertUser(@RequestBody UserDto user){
        return userService.insertUser(user);
    }

    @GetMapping("") // CRUD의 R
    public List<UserDto> getAllUsers(){
        return userService.getAllUsers();
    }

    @GetMapping("/{userId}")
    // @PathVariable로 URL에 변수를 넘겨준다.
    public UserDto getUserByUserId(@PathVariable String userId){
        return userService.getUserByUserId(userId);
    }

    @PutMapping("/{userId}") // CRUD의 U
    public void updateUserPw(@PathVariable String userId, @RequestBody UserDto user){
        userService.updateUserPw(userId, user);
    }

    @DeleteMapping("/{userId}") // CRUD의 D
    public void deleteUser(@PathVariable String userId){
        userService.deleteUser(userId);
    }

}

 

테스트

이제 Postman을 활용하여 구현한 CRUD가 잘 작동하는지 확인해 보자!

서버도 잘 돌아간다! localhost:8080에서 잘 되는지 테스트해보자.

 

먼저 GET방식 request를 보내 추가했었던 더미 데이터들을 불러와보자.

성공적이다.

 

POST 방식으로도 request를 보내보자! 보내는 데이터는 반드시 json형식으로 작성하자. raw를 선택하고 옵션을 json으로 선택해 주자.

성공적이다.

 

수정/삭제도 잘 되는 것을 확인했다!

 

참고자료

https://mangkyu.tistory.com/49

https://www.digitalocean.com/community/tutorials/spring-requestmapping-requestparam-pathvariable-example

https://www.geeksforgeeks.org/spring-rest-controller/

https://cheershennah.tistory.com/179

https://www.youtube.com/watch?v=mw2VrUkPG7I&ab_channel=%EC%84%B1%EC%A7%80%EC%B1%84%EB%84%90 

728x90