6. SpringBoot - JPA 를 사용해 간단한 RestApi 만들어 보기

JJo·2021년 6월 5일
1

React + SpringBoot

목록 보기
7/12

소개

오늘은 Spring Data Jpa 를 사용해서 간단한 유정정보에 대한 CRUD 를 처리하는 RestApi 를 만들어 보도록 하겠습니다.

Rest Api를 만들면서 배운 내용들을 복습하는 느낌으로 정리 하였기 때문에
내용이 번잡하거나 길수 있습니다.

Database 는 H2 Database 를 사용 하도록 하겠습니다 !

1 . H2 Database 설정

SrpingBoot properties

h2 설정

URL 과 name 을 이렇게 사용하도록 하겠습니다, password 는 따로 사용하지 않겠습니다.

Spring 에서 h2 Database에 접근할수 있도록 properties 를 설정 해주겠습니다.

application.properties

spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa

Table 생성

간단하게 이름(name), 나이(age) 정보를 가지는 Table를 생성 합니다.

Create Table User ( id int(5) PRIMARY KEY AUTO_INCREMENT, name varchar(10), age int(2))

2. Entity

Entity Class ?

  • 실제로 DB Table 과 매핑되는 Class 입니다.
  • @Entity @Table @Column 같은 Annotation 을 사용합니다.

Entity 생성

h2 에서 생성한 Table 을 바탕으로 Entity Class를 생성 하도록 하겠습니다.

@Entity
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    @Column(name = "name")
    private String name;
    
    private int age;
    
    /*
    Getter, Setter
     */
}

Annotation

Entity 클래스 에서 사용되는 Annotation 에 대해서 알아 보겠습니다.

  • @Entity
    클래스를 Entity 클래스 역할을 하기 위해서 @Entity 를 붙여줘야 합니다.
    해당 클래스 이름으로 DB 의 테이블명에 자동으로 매핑 됩니다.
    만약, 다른 테이블에 매핑하고 싶으면 @Entity(name="테이블명") 을 지정해주면 원하는 테이블에 매핑 가능합니다.

  • @Id
    DB 테이블에 식별자 역할(Key)을 하는 컬럼에 매핑 됩니다.
    Java 의 Primitive 타입과 wrapper 타입 모두 사용 할 수 있습니다.

  • @GenerateValue
    Id (Key) 의 자동 생성전략 을 설정해주는 Annotation 입니다.
    속성으로 strategy(생성 전략)generator(생성기) 가 존재합니다.
    strategy 는 Default 값은 AUTO 이며 JPA 제공하는 4가지 방법이 존재합니다.
    1. AUTO : DB에 맞게 자동 선택
    2. IDENTITY : DB의 identity 컬럼을 이용
    3. SEQUENCE : DB의 시퀀스 컬럼을 이용
    4. TABLE : 유일성이 보장된 데이터베이스 테이블을 이용

  • @Column
    해당 멤버가 DB 의 테이블명에 매핑됩니다. 기본적으로 Entity 클래스의 변수는 @Column 어노테이션이 부착되어 있습니다.
    (name ="column명") 을 사용하여 원하는 컬럼과 매핑 가능합니다.
    unique, nullable , length 등 다양한 속성을 통해서 제약조건을 설정 할 수 있습니다.

  • @Temporal
    시간, 날짜 타입으로 매핑하기 위해 사용합니다.

  • @Transient
    해당 변수를 DB의 컬럼에 매핑하지 않는 변수로 사용합니다.

3. Repository

이제 Entity 클래스를 생성하였으니, Repository 를 생성 해보도록 하겠습니다.

Repository ?

실제로 DB 와 소통하고 접근하는 객채를 말합니다. Service 와 DB 사이의 연결고리를 하는 역할입니다 !
DAO ( Data Access Object) 같은 역할을 하게 됩니다.

JpaRepository

Spring Data Jpa 를 사용하기 위해서 JpaRepository 를 만들어서 사용 하겠습니다.

  • JpaRepository 는 interface 형식으로 제공됩니다.

  • JpaRepository 를 사용하게되면 간단한 CRUD 작업은 쿼리문 생성없이 간편하게 사용 할 수 있습니다. 메소드 이름 형식으로 쿼리를 생성해 사용하게 됩니다.

Repository 생성

JpaRepository 를 사용하기 위해
public interface 'Repository명' extends JpaRepository <엔티티, ID 타입>
interface 를 생성합니다.

public interface JpaUserRepository extends JpaRepository<User, Long> {
    @Override // Create, Update
    User save(User user);

    @Override // Read
    Optional<User> findById(Long id);

    @Override // Delete
    void deleteById(Long id);
}

메소드 이름 형식으로 메소드 이름 만으로도 손쉽게 CRUD 기능을 만들 수 있습니다.

findByIdAndName 형식 처럼 AndOr 연산자도 사용 가능합니다.

반환값으로 save() 메소드는 Entity를 findBy() 메소드는 List< Entity>, Optional<> 형식으로 반환해주고 있습니다.

4. Service

Service ?

ServiceBusiness Logic 이 담긴, Repository 가 DB 에서 받아온 데이터들을 실질적 으로 가공하는 곳 입니다.

@Service 어노테이션을 통해 클래스를 Service 로 등록하여 사용합니다.

Service 생성

@Service
public class UserService {

    private JpaUserRepository jpaUserRepository;

    @Autowired // Constructor 를 사용한 Autowired
    public UserService(JpaUserRepository jpaUserRepository) {
        this.jpaUserRepository = jpaUserRepository;
    }

    public User create(User user) {
        return jpaUserRepository.save(user);
    }

    public Optional<User> read(Long id) {
        return jpaUserRepository.findById(id);
    }

    public User update(Long id,int age) {
        User user = read(id).get();
        user.setAge(age);
        return jpaUserRepository.save(user);
    }

    public void delete(Long id) {
        jpaUserRepository.deleteById(id);
    }
}

@Autowired 를 통해서 Repository의존성 주입(Di) 해주었습니다.
Spring 4.3 부터는 생성자가 1개일 경우 생략 가능합니다.

5. Controller

Controller ?

요청되는 Url 에 따라서 View 을 반환하거나 Data 를 반환해주는 응답을 해주는 역할을 하게됩니다.

전통적인 Spring MVC 패턴에서는 @Controller 를 통해서 view 를 응답하고, Restful Api로 사용될때는 @RestController 를 통해서 Response Body를 생성해 응답해 줍니다.

Controller 생성

Rest Api로 사용 하기 때문에 @RestController 를 이용하도록 하겠습니다.

@CrossOrigin (origins = "http://localhost:3000")
@RestController
@RequestMapping("/user")
public class UserController {

    private final UserService userService;

    @Autowired // Constructor 를 통한 Di
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/create")
    public ResponseEntity<User> create(@RequestBody User user) {
        return ResponseEntity.ok()
                .body(userService.create(user));
    }

    @GetMapping("/read/{id}")
    public ResponseEntity<User> read(@PathVariable Long id) {
        return ResponseEntity.ok()
                .body(userService.read(id).get());
    }
    @PutMapping("/update")
    public ResponseEntity<User> read(@RequestParam Long id, @RequestParam int age) {
        return ResponseEntity.ok()
                .body(userService.update(id,age));
    }

    @DeleteMapping("/delete/{id}")
    public void delete(@PathVariable Long id) {
        userService.delete(id);
    }
}
  1. @CrossOrigin (origins ="http://localhost:3000")
    프론트엔드 , 백엔드 서버가 분리 되어있기 때문에 CORS 문제가 발 생하게 됩니다. 정상으로 통신하기 위해서 @CrossOrigin 어노테이션을 통해 해당 도메인에서 접근을 허용해줍니다.

  2. @RestController
    Spring 에서 Controller 를 지정해줄때 @Controller , @RestController 를 사용하게 됩니다.
    Spring MVC 패턴에 서는 @Controller 를 사용한 View 응답이 주로 사용됩니다.
    Restful api 에서는 @RequestMapping@ResponseBody 를 포함한 @RestController 를 사용하게 됩 니다.

  3. @RequestMapping
    HTTP Request 로 들어오는 Url 요청을 특정 Method 와 Class 에 매핑 시켜주는 역할을 합니다. Class Level 로@RequestMapping("/user") 을 해주면 /user 경로로 요청이 들어오면 해당 클래스를 매핑시켜 줍니다.

  4. @GetMapping @PostMapping
    @RequestMapping 은 기본적으로 모든 Method 방식을 지원합니다.
    Method 방식을 Get, Post 로 사용하는것이 @GetMapping @PostMapping 입니다.

  5. @PathVariable
    Url 요청 경로에 변수를 담아서 요청 받을때 사용하게 됩니다.
    @PathVariable 으로 선언된 변수명을 통해서 해당 값을 읽어오게 됩니다.

  6. @RequestParam
    Http 에서 Parameter 로 넘어오는 값을 받아 올 수 있습니다.
    @RequestParam 으로 선언된 변수명을 통해서 해당 값을 읽어오게 됩니다.

6. SpringConfig

생성한 Service 를 @Bean 등록을 하겠습니다.

public class SpringConfig {
    private final JpaUserRepository jpaUserRepository;

    //DI 해주기 외부에서 jpaUserRepository 넣어주기
    @Autowired
    public SpringConfig(JpaUserRepository jpaUserRepository) {
        this.jpaUserRepository = jpaUserRepository;
    }

    @Bean
    public UserService userService() {
        return new UserService(jpaUserRepository);
    }
}

7. 동작 확인

React 에서 Controller 에 등록한 해당 Url로 요청을 하게 되면 동작하는 것을 확인 할 수 있습니다.


정상적으로 Data가 DB 에 등록하는 것을 알 수 있습니다.


정상적으로 DB 에 등록된 Data를 읽어 오는걸 알 수 있습니다.

정상적으로 DB 에 등록된 Data를 수정 하는걸 알 수 있습니다.

정상적으로 DB 에 등록된 Data를 삭제 하는걸 알 수 있습니다.

마침

CRUD 기능을 갖춘 간단한 Rest Api를 만들어 보았습니다.

profile
안녕하세용!!!

0개의 댓글