본문 바로가기
[ Programming ] Project/React JS CRUD with Spring Boot

[리액트, 스프링부트 연동하여 CRUD 구현] #10 - VO, Controller, Config, Mapper 작성 (10/10)

by the_little_coder 2020. 1. 23.

리액트, 스프링부트 연동하여 CRUD 구현

#10 - VO, Controller, Config, Mapper 작성



이제 마지막입니다. 이번 글에서는 VO, Controller, Configuration, 그리고 Mapper를 작성할겁니다. 각자의 역할을 알아보겠습니다. 


우리는 리액트에서 유저를 등록 할 때 "user"라는 객체에 정보를 담았고, ApiService 통해 스프링부트에게 URL로 작업을 요청했습니다. 리액트 언어와 자바의 언어는 다르기 때문에 자바 언어로 객체를 받아주어야 합니다. 이를 VO(Value Object)라고 합니다. 그리고 URL로 들어온 요청을 처리해주는 곳이 Controller입니다. Controller에서는 요청한 URL과 method(get,  post, delete 등)로 작업을 처리합니다. 우리는 흔히 Controller에서 DB를 다루는 작업을 많이 합니다. 저는 컨트롤러에서의 DB 작업을 MyBatis로 하겠습니다. MyBatis는 자바 Controller에서 DB 다루는 작업을 용이하게 해주는 라이브러리입니다. 이를 mapper라는 이름으로 총 2번, java파일과 xml파일로 작업을 합니다. xml파일에서 작성한 쿼리문을 java파일에서 작성한 메소드와 연결시켜 DB에서 작업을 합니다. 어설프게 설명했지만 백문이불여일견(百聞而不如一見)이니 이제 코드를 작성하겠습니다.



저는 이렇게 구조를 잡았습니다.





앞으로 작성할 파일은 5개입니다. CORSFilter.java, UserController.java, UserMapper.java, UserVO.java, 그리고 UserMapper.xml 입니다. application.properties파일은 #8에서 작성했으니 참고하시기 바랍니다. 다른건 대충 알겠지만, 아마 CORSFilter.java는 생소하실겁니다. 이 파일을 지운다면 실행이 되지 않을겁니다. 이유는? 시간이 되면 작성하겠습니다..ㅠ 구글에 "CORS"라고 검색하시면 잘 나올겁니다. 이제 작성하겠습니다.



CORSFilter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.demo.config;
 
import java.io.IOException;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class CORSFilter implements Filter{
 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
 
        System.out.println("필터링이 진행중입니다..."); //Console창에서 거슬린다면 주석처리 하셔도 됩니다!
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin""*");
        response.setHeader("Access-Control-Allow-Credentials""true");
        response.setHeader("Access-Control-Allow-Methods""POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Credentials""true");
        response.setHeader("Access-Control-Allow-Max-Age""3600");
        response.setHeader("Access-Control-Allow-Headers""X-Requested-With, Content-Type, "
                + "Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers");
        
        chain.doFilter(req, res);
    }
    
    public void init(FilterConfig filterConfig) {}
    
    public void destory() {}
}
 
cs



--- (절취선) ---


(2020.02.26. 추가)


댓글에서 설명한 것 처럼 이 파일을 작성해도 되고, 아니면 Controller를 담당하는 자바파일에서 @CrossOrigin 어노테이션을 작성하시면 됩니다. (단, 스프링 4.2버전 이상이어야 합니다!) 후자가 더 간단하기에 CORSFilter.java 파일을 작성하지 않고 밑에 UserController.java 파일에서 @CrossOrigin 어노테이션을 작성하세요.


--- (절취선) ---



UserVO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.example.demo.vo;
 
import lombok.Data;
 
@Data
public class UserVO {
 
    int id;
    String username;
    String password;
    String firstName;
    String lastName;
    int age;
    int salary;
    
}
cs



UserMapper.java (Interface)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.example.demo.mapper;
 
import java.util.List;
 
import org.apache.ibatis.annotations.Mapper;
 
import com.example.demo.vo.UserVO;
 
@Mapper
public interface UserMapper {
 
    List<UserVO> userList();
    UserVO fetchUserByID(int id);
    void updateUser(UserVO user);
    void insertUser(UserVO user);
    void deleteUser(int id);
}
 
cs



UserMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTDMapper3.0//EN" 
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <mapper namespace="com.example.demo.mapper.UserMapper">
  
      <insert id="insertUser" parameterType="com.example.demo.vo.UserVO">
          INSERT INTO users(username, password, firstName, lastName, age, salary)
          VALUES(#{username}, #{password}, #{firstName}, #{lastName}, #{age}, #{salary})
      </insert>
  
     <select id="userList" resultType="com.example.demo.vo.UserVO">
         SELECT * FROM users
         ORDER BY id
     </select>
     
     <select id="fetchUserByID" resultType="com.example.demo.vo.UserVO"
      parameterType="int">
         SELECT * FROM users
         WHERE id = #{id}
     </select>
     
     <delete id="deleteUser" parameterType="int">
         DELETE FROM users
         WHERE id = #{id}
     </delete>
     
     <update id="updateUser" parameterType="com.example.demo.vo.UserVO">
         UPDATE users
         SET firstName = #{firstName}, lastName = #{lastName}, age = #{age}, salary = #{salary} 
         WHERE id = #{id}
     </update>
  
  </mapper>
cs



UserController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.example.demo.controller;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import com.example.demo.mapper.UserMapper;
import com.example.demo.vo.UserVO;
 
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/users")
public class UserController {
 
    @Autowired
    UserMapper userMapper;
    
    @GetMapping
    public List<UserVO> userList(){
        System.out.println(userMapper.userList());
        System.out.println("유저리스트 출력 성공");
        return userMapper.userList();
    }
    
    @PostMapping
    void insertUser(@RequestBody UserVO user) {
        userMapper.insertUser(user);
        System.out.println("유저 DB 저장 성공");
    }
    
    @GetMapping("/{id}")
    public UserVO fetchUserByID(@PathVariable int id) {
        System.out.println(userMapper.fetchUserByID(id));
        UserVO fetchUser = userMapper.fetchUserByID(id);
        return fetchUser;
    }
        
    @PutMapping("/{id}")
    public void updateUser(@PathVariable int id, @RequestBody UserVO user) {
        
        UserVO updateUser = user;
        System.out.println("업데이트유저 => " + updateUser);
        
        updateUser.setFirstName(user.getFirstName());
        updateUser.setLastName(user.getLastName());
        updateUser.setAge(user.getAge());
        updateUser.setSalary(user.getSalary());
        
        userMapper.updateUser(updateUser); 
    }
    
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable int id) {
        userMapper.deleteUser(id);
        System.out.println("유저 삭제, 성공적");
    }
    
}
cs



다 작성하셨다면 리액트와 스프링부트를 둘 다 켜서 http://localhost:3000/에서 확인해보세요. 그리고 유저를 작성하고, 수정하고, 삭제까지 해 보세요. 잘 되나요?(잘 될거에요!) 에러나신다거나 궁굼하신 점 있으시면 댓글 달아주세요. 여러분, 정말 고생하셨어요! 





댓글