-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
부산대 BE_박수빈_1주차 과제(3단계) #192
base: main
Are you sure you want to change the base?
Changes from all commits
d507b5a
88a8c34
98364e4
2b0b99d
408d83d
0a5204a
f9002a7
c398921
1c0fe9f
5975ea0
49f08e2
7984606
782460f
a9fc3ec
f143517
5f2b48e
41746f6
431407d
cff1d4a
75d86ee
40baf95
ecf9a78
c6958fe
07be71a
9bca0b5
4e0e9d9
fd85414
3d41a71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,8 @@ | ||
# spring-gift-product | ||
# spring-gift-product | ||
|
||
1. database로 연결하는 과정에서 | ||
gradle 버전 , jdk 버전 등등에 의해 상당히 영향을 많이 받았고 | ||
또한 의존성 충돌 , propertise 충돌에 의해서 실행되지 않는 일이 | ||
많았습니다. 그래서 더 과제가 힘들었던것 같습니다. | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package gift; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Table; | ||
|
||
@Entity | ||
@Table(name = "product") | ||
public class Product { | ||
kuma4188 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.AUTO) | ||
private Long id; | ||
private String name; | ||
private int price; | ||
@Column(name = "image_url", nullable = false) | ||
private String imageUrl; | ||
|
||
public Product() { | ||
|
||
} | ||
|
||
|
||
// create getter | ||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public String getImageUrl() { | ||
return imageUrl; | ||
} | ||
|
||
public int getPrice() { | ||
return price; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
// create setter | ||
public void setId(Long id) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 id 필드는 데이터베이스에서 자동으로 생성(auto_increment) & 관리되고 있어요. |
||
this.id = id; | ||
} | ||
|
||
public void setImageUrl(String imageUrl) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 사용하지 않는 getter, setter는 지우는 것이 좋습니다.! |
||
this.imageUrl = imageUrl; | ||
} | ||
|
||
public void setPrice(int price) { | ||
this.price = price; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package gift; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface ProductRepository extends JpaRepository<Product, Long> { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package gift; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import java.util.List; | ||
|
||
@Service | ||
@Transactional // 서비스 메서드에 대한 트랜잭션 관리 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 트랜잭션 관리를 위해 |
||
public class ProductService { | ||
|
||
private final ProductRepository productRepository; | ||
|
||
@Autowired | ||
public ProductService(ProductRepository productRepository) { | ||
this.productRepository = productRepository; | ||
} | ||
|
||
@Transactional(readOnly = true) // 읽기 전용 트랜잭션 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 읽기 전용 트랜잭션은 성능 최적화와 코드의 의도를 명확히 하는 데 도움이 될 수 있지만 반드시 필요한 것은 아닙니다. |
||
public List<Product> getAllProducts() { | ||
return productRepository.findAll(); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public Product getProductById(Long id) { | ||
return productRepository.findById(id) | ||
.orElseThrow(() -> new IllegalArgumentException("Invalid product Id:" + id)); | ||
} | ||
|
||
@Transactional | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
따라서 이 메서드들에 별도로 |
||
public void saveProduct(Product product) { | ||
productRepository.save(product); | ||
} | ||
|
||
@Transactional | ||
public void updateProduct(Long id, Product product) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 존재하지 않는 제품의 id로 요청하는 경우 어떻게 될까요? |
||
product.setId(id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 앞서 말씀드린 것 처럼, 객체에 수동으로 id를 설정하고 저장하는 것은 권장하지 않습니다. 데이터베이스에서 기존 엔티티를 가져온 다음에 수정해볼까요? |
||
productRepository.save(product); | ||
} | ||
|
||
@Transactional | ||
public void deleteProduct(Long id) { | ||
productRepository.deleteById(id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기도 마찬가지로 존재하지 않는 제품의 id로 삭제 요청하는 경우 어떻게 될까요? |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package gift; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.ui.Model; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.List; | ||
|
||
@Controller | ||
@RequestMapping("/web/products") | ||
public class ProductWebController { | ||
|
||
private final ProductService productService; | ||
|
||
@Autowired | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 생성자가 하나만 있는 경우, |
||
public ProductWebController(ProductService productService) { | ||
this.productService = productService; | ||
} | ||
|
||
@GetMapping("/list") | ||
public String getAllProducts(Model model) { | ||
List<Product> products = productService.getAllProducts(); | ||
model.addAttribute("products", products); | ||
return "productList"; // product list view의 이름을 반환 | ||
} | ||
|
||
@GetMapping("/detail/{id}") | ||
public String getProductById(@PathVariable("id") Long id, Model model) { | ||
Product product = productService.getProductById(id); | ||
model.addAttribute("product", product); | ||
return "productDetail"; // product detail view의 이름을 반환 | ||
} | ||
|
||
@GetMapping("/add") | ||
public String addProductForm(Model model) { | ||
model.addAttribute("product", new Product()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 데이터베이스 엔티티이자 도메인 객체인 |
||
return "addProduct"; // add product form view의 이름을 반환 | ||
} | ||
|
||
@PostMapping("/add") | ||
public String addProduct(@ModelAttribute Product product) { | ||
productService.saveProduct(product); | ||
return "redirect:/web/products/list"; // 상품 목록 페이지로 리다이렉트 | ||
} | ||
|
||
@GetMapping("/edit/{id}") | ||
public String editProductForm(@PathVariable("id") Long id, Model model) { | ||
Product product = productService.getProductById(id); | ||
model.addAttribute("product", product); | ||
return "editProduct"; // edit product form view의 이름을 반환 | ||
} | ||
|
||
@PostMapping("/edit/{id}") | ||
public String updateProduct(@PathVariable("id") Long id, @ModelAttribute Product product) { | ||
productService.updateProduct(id, product); | ||
return "redirect:/web/products/list"; // 상품 목록 페이지로 리다이렉트 | ||
} | ||
|
||
@GetMapping("/delete/{id}") | ||
public String deleteProduct(@PathVariable("id") Long id) { | ||
productService.deleteProduct(id); | ||
return "redirect:/web/products/list"; // 상품 목록 페이지로 리다이렉트 | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Google Java Style Guide 규칙 중 하나가 적용되지 않았네요!
IntelliJ 설정으로 쉽게 처리할 수 있으니 활성화하는 것을 추천드립니다.
프로젝트 전체적으로 코드 컨벤션이 적용 안된 것 같아요 (들여쓰기, 줄 띄우기, 공백 등) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,17 @@ | ||
spring.application.name=spring-gift | ||
|
||
spring.datasource.url=jdbc:h2:mem:test | ||
spring.datasource.driverClassName=org.h2.Driver | ||
spring.datasource.username=sa | ||
spring.datasource.password=password | ||
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect | ||
logging.level.org.springframework.jdbc=DEBUG | ||
logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG | ||
spring.h2.console.enabled=true | ||
spring.h2.console.path=/h2-console | ||
spring.datasource.initialization-mode=always | ||
spring.sql.init.schema-locations=classpath:/model/schema.sql | ||
spring.sql.init.data-locations=classpath:/model/data.sql | ||
logging.level.org.springframework.transaction=DEBUG | ||
|
||
spring.jpa.hibernate.ddl-auto=update |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
INSERT INTO product (name, price, image_url) VALUES ('아이스 카페 아메리카노 T', 4500, 'https://st.kakaocdn.net/product/gift/product/20231010111814_9a667f9eccc943648797925498bdd8a3.jpg'); | ||
INSERT INTO product (name, price, image_url) VALUES ('아이스 카페 라테 T', 5500, 'https://item.elandrs.com/upload/prd/orgimg/088/2005488088_0000001.jpg?w=750&h=&q=100'); | ||
INSERT INTO product (name, price, image_url) VALUES ('뜨거운 아이스 아메리카노 T', 6500, 'https://dimg.donga.com/wps/NEWS/IMAGE/2017/02/06/82727038.1.jpg'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 초기 데이터 설정 👏 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CREATE TABLE product ( | ||
id BIGINT AUTO_INCREMENT PRIMARY KEY, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
name VARCHAR(255) NOT NULL, | ||
price INT NOT NULL, | ||
image_url VARCHAR(1000) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. image_url에 NOT NULL 제약 조건이 빠졌네요. |
||
); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!DOCTYPE html> | ||
<html xmlns:th="http://www.thymeleaf.org"> | ||
<head> | ||
<title>404 - Not Found</title> | ||
</head> | ||
<body> | ||
<h1>404 - Not Found</h1> | ||
<p>The requested resource was not found on this server.</p> | ||
<a href="/products">Back to List</a> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<!DOCTYPE html> | ||
<html xmlns:th="http://www.thymeleaf.org"> | ||
<head> | ||
<title>Add Product</title> | ||
</head> | ||
<body> | ||
<h1>Add Product</h1> | ||
<form th:action="@{/web/products/add}" th:object="${product}" method="post"> | ||
<p>Name: <input type="text" th:field="*{name}"/></p> | ||
<p>Price: <input type="text" th:field="*{price}"/></p> | ||
<p>Image URL: <input type="text" th:field="*{imageUrl}"/></p> | ||
<button type="submit">Add Product</button> | ||
</form> | ||
<a href="/web/products/list">Back to List</a> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!DOCTYPE html> | ||
<html xmlns:th="http://www.thymeleaf.org"> | ||
<head> | ||
<title>Edit Product</title> | ||
</head> | ||
<body> | ||
<h1>Edit Product</h1> | ||
<form th:action="@{/web/products/edit/{id}(id=${product.id})}" th:object="${product}" method="post"> | ||
<input type="hidden" th:field="*{id}"/> | ||
<p>Name: <input type="text" th:field="*{name}"/></p> | ||
<p>Price: <input type="text" th:field="*{price}"/></p> | ||
<p>Image URL: <input type="text" th:field="*{imageUrl}"/></p> | ||
<button type="submit">Update Product</button> | ||
</form> | ||
<a href="/web/products/list">Back to List</a> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<!DOCTYPE html> | ||
<html xmlns:th="http://www.thymeleaf.org"> | ||
<head> | ||
<title>Product Detail</title> | ||
</head> | ||
<body> | ||
<h1>Product Detail</h1> | ||
<p>ID: <span th:text="${product.id}">1</span></p> | ||
<p>Name: <span th:text="${product.name}">Name</span></p> | ||
<p>Price: <span th:text="${product.price}">Price</span></p> | ||
<img th:src="${product.imageUrl}" alt="product image" width="200"/> | ||
<br> | ||
<a href="/web/products/list">Back to List</a> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<!DOCTYPE html> | ||
<html xmlns:th="http://www.thymeleaf.org"> | ||
<head> | ||
<title>Product List</title> | ||
</head> | ||
<body> | ||
<h1>Product List</h1> | ||
<a href="/web/products/add">Add New Product</a> | ||
<table> | ||
<thead> | ||
<tr> | ||
<th>ID</th> | ||
<th>Name</th> | ||
<th>Price</th> | ||
<th>Image</th> | ||
<th>Actions</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr th:each="product : ${products}"> | ||
<td th:text="${product.id}">1</td> | ||
<td th:text="${product.name}">Name</td> | ||
<td th:text="${product.price}">Price</td> | ||
<td><img th:src="${product.imageUrl}" alt="product image" width="100"/></td> | ||
<td> | ||
<a th:href="@{/web/products/detail/{id}(id=${product.id})}">View</a> | ||
<a th:href="@{/web/products/edit/{id}(id=${product.id})}">Edit</a> | ||
<a th:href="@{/web/products/delete/{id}(id=${product.id})}">Delete</a> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</body> | ||
</html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
버전 충돌때문에 많은 일들이 있으셨군요 ㅠ_ㅠ 1주차 고생 많으셨어요
저는 보통 버전 문제가 있을 때 이렇게 찾아보곤 합니다.
./gradlew dependencies
으로 의존성 트리를 체크해서 충돌되는 라이브러리를 파악해서 버전 조정하기./gradlew clean build
해보기