728x90
반응형
##AllInOneController -> 기능 별 controller,service,repository 3계층으로 리팩토링 하기
-아래의 코드는 절차지향이라 코드가 길고 복잡하게 보인다. 이것을 객체지향으로 바꾸자
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
package com.sparta_spring.sparta_springcore_week01;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다.
@RestController // JSON으로 데이터를 주고받음을 선언합니다. @Controller , @ResponseBody 2개의 역할 합침
public class AllInOneController {
// 등록된 전체 상품 목록 조회
@GetMapping("/api/products")
public List<Product> getProducts() throws SQLException {
ArrayList<Product> products = new ArrayList<>();
// DB 연결
Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", "sa", "");
// DB Query 작성 및 실행
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select * from product");
// DB Query 결과를 상품 객체 리스트로 변환
while (rs.next()) {
Product product = new Product();
product.setId(rs.getLong("id"));
product.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime());
product.setModifiedAt(rs.getTimestamp("modified_at").toLocalDateTime());
product.setImage(rs.getString("image"));
product.setLink(rs.getString("link"));
product.setLprice(rs.getInt("lprice"));
product.setMyprice(rs.getInt("myprice"));
product.setTitle(rs.getString("title"));
products.add(product);
}
// DB 연결 해제
rs.close();
connection.close();
// 응답 보내기
return products;
}
// 신규 상품 등록
@PostMapping("/api/products")
public Product createProduct(@RequestBody ProductRequestDto requestDto) throws SQLException {
// 요청받은 DTO 로 DB에 저장할 객체 만들기
Product product = new Product(requestDto);
LocalDateTime now = LocalDateTime.now();
product.setCreatedAt(now);
product.setModifiedAt(now);
// DB 연결
Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", "sa", "");
// DB Query 작성
PreparedStatement ps = connection.prepareStatement("select max(id) as id from product");
ResultSet rs = ps.executeQuery();
if (rs.next()) {
// product id 설정 = product 테이블의 마지막 id + 1
product.setId(rs.getLong("id") + 1);
} else {
throw new SQLException("product 테이블의 마지막 id 값을 찾아오지 못했습니다.");
}
ps = connection.prepareStatement("insert into product(id, title, image, link, lprice, myprice, created_at, modified_at) values(?, ?, ?, ?, ?, ?, ?, ?)");
ps.setLong(1, product.getId());
ps.setString(2, product.getTitle());
ps.setString(3, product.getImage());
ps.setString(4, product.getLink());
ps.setInt(5, product.getLprice());
ps.setInt(6, product.getMyprice());
ps.setString(7, product.getCreatedAt().toString());
ps.setString(8, product.getModifiedAt().toString());
// DB Query 실행
ps.executeUpdate();
// DB 연결 해제
ps.close();
connection.close();
// 응답 보내기
return product;
}
// 설정 가격 변경
@PutMapping("/api/products/{id}")
public Long updateProduct(@PathVariable Long id, @RequestBody ProductMypriceRequestDto requestDto) throws SQLException {
Product product = new Product();
// DB 연결
Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", "sa", "");
// DB Query 작성
PreparedStatement ps = connection.prepareStatement("select * from product where id = ?");
ps.setLong(1, id);
// DB Query 실행
ResultSet rs = ps.executeQuery();
if (rs.next()) {
product.setId(rs.getLong("id"));
product.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime());
product.setModifiedAt(rs.getTimestamp("modified_at").toLocalDateTime());
product.setImage(rs.getString("image"));
product.setLink(rs.getString("link"));
product.setLprice(rs.getInt("lprice"));
product.setMyprice(rs.getInt("myprice"));
product.setTitle(rs.getString("title"));
} else {
throw new NullPointerException("해당 아이디가 존재하지 않습니다.");
}
// DB Query 작성
ps = connection.prepareStatement("update product set myprice = ?, modified_at = ? where id = ?");
ps.setInt(1, requestDto.getMyprice());
ps.setString(2, LocalDateTime.now().toString());
ps.setLong(3, product.getId());
// DB Query 실행
ps.executeUpdate();
// DB 연결 해제
rs.close();
ps.close();
connection.close();
// 응답 보내기 (업데이트된 상품 id)
return product.getId();
}
}
|
cs |
2.ProductController 역할 분리
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
|
package com.sparta_spring.sparta_springcore_week01;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.sql.SQLException;
import java.util.List;
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다.
@RestController // JSON으로 데이터를 주고받음을 선언합니다.
public class ProductController {
// 등록된 전체 상품 목록 조회
@GetMapping("/api/products")
public List<Product> getProducts() throws SQLException {
ProductService productService = new ProductService();
List<Product> products = productService.getProducts();
// 응답 보내기
return products;
}
// 신규 상품 등록
@PostMapping("/api/products")
public Product createProduct(@RequestBody ProductRequestDto requestDto) throws SQLException {
ProductService productService = new ProductService();
Product product = productService.createProduct(requestDto);
// 응답 보내기
return product;
}
// 설정 가격 변경
@PutMapping("/api/products/{id}")
public Long updateProduct(@PathVariable Long id, @RequestBody ProductMypriceRequestDto requestDto) throws SQLException {
ProductService productService = new ProductService();
Product product = productService.updateProduct(id, requestDto);
return product.getId();
}
}
|
cs |
3.ProductService 역할 분리
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
|
package com.sparta_spring.sparta_springcore_week01;
import java.sql.SQLException;
import java.util.List;
public class ProductService {
public List<Product> getProducts() throws SQLException {
ProductRepository productRepository = new ProductRepository();
return productRepository.getProducts();
}
public Product createProduct(ProductRequestDto requestDto) throws SQLException {
ProductRepository productRepository = new ProductRepository();
// 요청받은 DTO 로 DB에 저장할 객체 만들기
Product product = new Product(requestDto);
productRepository.createProduct(product);
return product;
}
public Product updateProduct(Long id, ProductMypriceRequestDto requestDto) throws SQLException {
// 최저가 0 미만 예외처리
if(requestDto.getMyprice() < 0){
throw new IllegalAccessError("최저가는 0 이상입니다.");
}
ProductRepository productRepository = new ProductRepository();
Product product = productRepository.getProduct(id);
if (product == null) {
throw new NullPointerException("해당 아이디가 존재하지 않습니다.");
}
int myPrice = requestDto.getMyprice();
productRepository.updateProductMyPrice(id, myPrice);
return product;
}
}
|
cs |
4.ProductRepository 역할 분리
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
package com.sparta_spring.sparta_springcore_week01;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
public class ProductRepository {
public Product getProduct(Long id) throws SQLException {
Product product = new Product();
// DB 연결
Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", "sa", "");
// DB Query 작성
PreparedStatement ps = connection.prepareStatement("select * from product where id = ?");
ps.setLong(1, id);
// DB Query 실행
ResultSet rs = ps.executeQuery();
if (rs.next()) {
product.setId(rs.getLong("id"));
product.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime());
product.setModifiedAt(rs.getTimestamp("modified_at").toLocalDateTime());
product.setImage(rs.getString("image"));
product.setLink(rs.getString("link"));
product.setLprice(rs.getInt("lprice"));
product.setMyprice(rs.getInt("myprice"));
product.setTitle(rs.getString("title"));
} else {
return null;
}
return product;
}
public List<Product> getProducts() throws SQLException {
ArrayList<Product> products = new ArrayList<>();
// DB 연결
Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", "sa", "");
// DB Query 작성 및 실행
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select * from product");
// DB Query 결과를 상품 객체 리스트로 변환
while (rs.next()) {
Product product = new Product();
product.setId(rs.getLong("id"));
product.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime());
product.setModifiedAt(rs.getTimestamp("modified_at").toLocalDateTime());
product.setImage(rs.getString("image"));
product.setLink(rs.getString("link"));
product.setLprice(rs.getInt("lprice"));
product.setMyprice(rs.getInt("myprice"));
product.setTitle(rs.getString("title"));
products.add(product);
}
// DB 연결 해제
rs.close();
connection.close();
return products;
}
public void createProduct(Product product) throws SQLException {
LocalDateTime now = LocalDateTime.now();
product.setCreatedAt(now);
product.setModifiedAt(now);
// DB 연결
Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", "sa", "");
// DB Query 작성
PreparedStatement ps = connection.prepareStatement("select max(id) as id from product");
ResultSet rs = ps.executeQuery();
if (rs.next()) {
// product id 설정 = product 테이블의 마지막 id + 1
product.setId(rs.getLong("id") + 1);
} else {
throw new SQLException("product 테이블의 마지막 id 값을 찾아오지 못했습니다.");
}
// DB Query 작성
ps = connection.prepareStatement("insert into product(id, title, image, link, lprice, myprice, created_at, modified_at) values(?, ?, ?, ?, ?, ?, ?, ?)");
ps.setLong(1, product.getId());
ps.setString(2, product.getTitle());
ps.setString(3, product.getImage());
ps.setString(4, product.getLink());
ps.setInt(5, product.getLprice());
ps.setInt(6, product.getMyprice());
ps.setString(7, product.getCreatedAt().toString());
ps.setString(8, product.getModifiedAt().toString());
// DB Query 실행
ps.executeUpdate();
// DB 연결 해제
ps.close();
connection.close();
}
public void updateProductMyPrice(Long id, int myPrice) throws SQLException {
// DB 연결
Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", "sa", "");
// DB Query 작성
PreparedStatement ps = connection.prepareStatement("update product set myprice = ?, modified_at = ? where id = ?");
ps.setInt(1, myPrice);
ps.setString(2, LocalDateTime.now().toString());
ps.setLong(3, id);
// DB Query 실행
ps.executeUpdate();
// DB 연결 해제
ps.close();
connection.close();
}
}
|
cs |
##리팩토링 후 검증
1.리팩토링이란?
: 기능은 똑같이 하되 편의에 맞춰 내부구조나 코드를 바꾸는 것.
반응형
'SpringBoot > 스파르타 스프링 심화' 카테고리의 다른 글
[스파르타 스프링 심화] 01.15 DI (dependency Injection,의존성 주입) 사용하기 , Ioc(제어의 역전) (0) | 2021.08.12 |
---|---|
[스파르타 스프링 심화] 01.14. DI (의존성 주입)의 이해 (0) | 2021.08.12 |
[스파르타 스프링 심화] 01.11 관심사 분리해보기 (0) | 2021.08.12 |
[스파르타 스프링 심화] 01.10 객체지향 프로그래밍 (0) | 2021.08.12 |
[스파르타 스프링 심화] 01.09. AllInOneController(절차지향) 의 문제점 (0) | 2021.08.12 |