diff --git a/README.md b/README.md index cafde8a2c..ef493e159 100644 --- a/README.md +++ b/README.md @@ -1 +1,8 @@ -# spring-gift-product \ No newline at end of file +# spring-gift-product + +1. database로 연결하는 과정에서 +gradle 버전 , jdk 버전 등등에 의해 상당히 영향을 많이 받았고 +또한 의존성 충돌 , propertise 충돌에 의해서 실행되지 않는 일이 +많았습니다. 그래서 더 과제가 힘들었던것 같습니다. + + diff --git a/build.gradle b/build.gradle index df7db9334..664eac6c2 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,8 @@ repositories { } dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.data:spring-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' @@ -26,6 +28,8 @@ dependencies { testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } + + tasks.named('test') { useJUnitPlatform() } diff --git a/src/main/java/gift/Application.java b/src/main/java/gift/Application.java index 61603cca0..8d092e6f6 100644 --- a/src/main/java/gift/Application.java +++ b/src/main/java/gift/Application.java @@ -2,8 +2,13 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + @SpringBootApplication +@EnableJpaRepositories(basePackages = "gift") +@EntityScan("gift") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); diff --git a/src/main/java/gift/Product.java b/src/main/java/gift/Product.java new file mode 100644 index 000000000..a94cbe752 --- /dev/null +++ b/src/main/java/gift/Product.java @@ -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 { + @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) { + this.id = id; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public void setPrice(int price) { + this.price = price; + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/src/main/java/gift/ProductRepository.java b/src/main/java/gift/ProductRepository.java new file mode 100644 index 000000000..382e66852 --- /dev/null +++ b/src/main/java/gift/ProductRepository.java @@ -0,0 +1,6 @@ +package gift; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ProductRepository extends JpaRepository { +} diff --git a/src/main/java/gift/ProductService.java b/src/main/java/gift/ProductService.java new file mode 100644 index 000000000..08b98239b --- /dev/null +++ b/src/main/java/gift/ProductService.java @@ -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 // 서비스 메서드에 대한 트랜잭션 관리 +public class ProductService { + + private final ProductRepository productRepository; + + @Autowired + public ProductService(ProductRepository productRepository) { + this.productRepository = productRepository; + } + + @Transactional(readOnly = true) // 읽기 전용 트랜잭션 + public List getAllProducts() { + return productRepository.findAll(); + } + + @Transactional(readOnly = true) + public Product getProductById(Long id) { + return productRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("Invalid product Id:" + id)); + } + + @Transactional + public void saveProduct(Product product) { + productRepository.save(product); + } + + @Transactional + public void updateProduct(Long id, Product product) { + product.setId(id); + productRepository.save(product); + } + + @Transactional + public void deleteProduct(Long id) { + productRepository.deleteById(id); + } +} diff --git a/src/main/java/gift/ProductWebController.java b/src/main/java/gift/ProductWebController.java new file mode 100644 index 000000000..c076cb184 --- /dev/null +++ b/src/main/java/gift/ProductWebController.java @@ -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 + public ProductWebController(ProductService productService) { + this.productService = productService; + } + + @GetMapping("/list") + public String getAllProducts(Model model) { + List 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()); + 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"; // 상품 목록 페이지로 리다이렉트 + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3d16b65f4..3e6775c21 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -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 \ No newline at end of file diff --git a/src/main/resources/model/data.sql b/src/main/resources/model/data.sql new file mode 100644 index 000000000..f10facb31 --- /dev/null +++ b/src/main/resources/model/data.sql @@ -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'); diff --git a/src/main/resources/model/schema.sql b/src/main/resources/model/schema.sql new file mode 100644 index 000000000..ac89129f8 --- /dev/null +++ b/src/main/resources/model/schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE product ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + price INT NOT NULL, + image_url VARCHAR(1000) +); + + diff --git a/src/main/resources/templates/404.html b/src/main/resources/templates/404.html new file mode 100644 index 000000000..f716548c0 --- /dev/null +++ b/src/main/resources/templates/404.html @@ -0,0 +1,11 @@ + + + + 404 - Not Found + + +

404 - Not Found

+

The requested resource was not found on this server.

+Back to List + + diff --git a/src/main/resources/templates/addProduct.html b/src/main/resources/templates/addProduct.html new file mode 100644 index 000000000..efdf5a3cb --- /dev/null +++ b/src/main/resources/templates/addProduct.html @@ -0,0 +1,16 @@ + + + + Add Product + + +

Add Product

+
+

Name:

+

Price:

+

Image URL:

+ +
+Back to List + + diff --git a/src/main/resources/templates/editProduct.html b/src/main/resources/templates/editProduct.html new file mode 100644 index 000000000..b6c040092 --- /dev/null +++ b/src/main/resources/templates/editProduct.html @@ -0,0 +1,17 @@ + + + + Edit Product + + +

Edit Product

+
+ +

Name:

+

Price:

+

Image URL:

+ +
+Back to List + + diff --git a/src/main/resources/templates/productDetail.html b/src/main/resources/templates/productDetail.html new file mode 100644 index 000000000..574b87f36 --- /dev/null +++ b/src/main/resources/templates/productDetail.html @@ -0,0 +1,15 @@ + + + + Product Detail + + +

Product Detail

+

ID: 1

+

Name: Name

+

Price: Price

+product image +
+Back to List + + diff --git a/src/main/resources/templates/productList.html b/src/main/resources/templates/productList.html new file mode 100644 index 000000000..bcdd22a22 --- /dev/null +++ b/src/main/resources/templates/productList.html @@ -0,0 +1,34 @@ + + + + Product List + + +

Product List

+Add New Product + + + + + + + + + + + + + + + + + + + +
IDNamePriceImageActions
1NamePriceproduct image + View + Edit + Delete +
+ +