개인 공부

MVC 패턴이 뭔데...

orin602 2024. 12. 18. 17:10

SpringBoot를 통한 프로젝트를 하다보니 내가 제대로 이게 어떤 기능이고, 어떻게 사용하는지에 대한 설명을 제대로 하지 못하는 모습을 보고 혼자 공부도 하고, 면접 준비를 위한 글입니다요.... 초보 개발자로 살아남기가 많이 힘드네요 ㅠ_ㅠ

 

MVC가 뭔데...  Model-View-Controller 랍니다!!! 이건 기본이겠죠..? 아무튼 이렇게 나눠서 구현하는 디자인 패턴이랍니다. application의 구성 요소를 분리하여 관리하기 쉽고, 코드의 유지보수성을 높이는데 도움을 준다는데.. 말이 너무 어렵네요. 

  • Model : 애플리케이션의 데이터와 비지니스 로직을 처리하며, DB(데이터베이스)와 상호작용을 하거나, 로직을 수행하는 역할.
  • View : 사용자에게 데이터를 시각적으로 표현. Html, Css, javaScript 등을 사용해 UI를 구성하는 역할.
  • Controller : 사용자의 요청을 처리하고, Model과 View를 연결하는 역할.

(공부하면서 글을 써도 뭔지 잘 이해가 되질 않아요.... 프로젝트 할 때 무너지는 알고 써야할텐데 너무 생각없이... 아니 어떻게 만들었냐...)

 

MVC는 어떻게 사용하는 건가....

(저는 Spring Boot위주로 프로젝트를 만들어서 Spring Boot로 예시를 들면서 설명하고 공부헤볼게요!!!)

기본적으로 Spring Boot에서 @Controller 이노테이션을 사용해서 클래스를 정의하고, @ModelAttribute나 @RequestMapping 등을 활용해 요청을 처리하는데요. Model은 주로 엔티티 클래스와 서비스 클래스를 통해 구현하고, View는 Thymeleaf, JSP 같은 템플릿 엔진을 사용해 구현할 수 있어요.

 

모델 정의

(클래스 생성)

package com.domain;

import java.util.Date;

import org.hibernate.annotations.ColumnDefault;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@Entity
public class Customer {

	@Id // 기본키
	@GeneratedValue(strategy=GenerationType.IDENTITY)	// 기본키 자동 증가
	private int customer_seq;
	
	private String id;
	private String password;
	private String name;
	
	@Temporal(value=TemporalType.TIMESTAMP)	// 날짜 + 시간
	@ColumnDefault("sysdate")
	private Date regdate;
}

 

Oracle DB

(Repository 생성) : 모델 클래승에 대한 데이터베이스 작업을 처리하기 위함.

package com.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.domain.Customer;

public interface CustomerRepository extends JpaRepository<Customer, Integer> {

}
  • Spring Data JPA를 사용하면 JpaRepository를 확장하여 CRUD 작업을 쉽게 할 수 있습니다.
  • JpaRepository는 save(), findById(), findAll(), delete()등 기본적인 CRUD 기능 제공.

(Service 생성) : 비즈니스 로직을 담당하는 계층으로 Repository와 상호작용해 데이터를 가져오고, 필요에 따라 가공하거나 다른 비즈니스 로직을 처리함.

package com.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.domain.Customer;
import com.repository.CustomerRepository;

@Service
public class CustomerService {

	@Autowired
	private CustomerRepository customerRepo;
	
	public List<Customer> getAllCustomer() {
		return customerRepo.findAll();	// 모든 회원을 찾음.
	}
	
	public Customer getCustomerById(int customer_seq) {
		return customerRepo.findById(customer_seq).orElse(null);
	}
	
	public void saveCustomer(Customer customer) {
		customerRepo.save(customer);
	}
	
	public void deleteCustomer(int customer_seq) {
		customerRepo.deleteById(customer_seq);
	}
}

 

(Controller 생성) : HTTP 요청(GET, POST, PUT, DELETE 등) 을 처리하고, Model 객체를 View에 전달하는 역할 및 서비스 계층을 호출해 데이터베이스에서 데이터를 가져옴.

package com.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.domain.Customer;
import com.service.CustomerService;

@Controller
public class CustomerController {

	@Autowired
	private CustomerService customerService;
	
	@GetMapping("/")
	public String listCustomers(Model model) {
		List<Customer> customers = customerService.getAllCustomer();
		model.addAttribute("customers", customers);
		return "customer/list";
	}
	
	// 회원가입 페이지
	@GetMapping("/join")
	public String joinView() {
		return "customer/join";
	}
	
	// 회원가입 처리
	@PostMapping("/join")
	public String joinAction(Customer customer) {
		customerService.saveCustomer(customer);
		return "redirect:/";
	}
	
	// 회원 탈퇴
	@GetMapping("/delete")
	public String deleteCustomer(@RequestParam("customer_seq") int customer_seq) {
		customerService.deleteCustomer(customer_seq);
		return "redirect:/";
	}
}
  • listCustomers 메서드 : customerService.getAllCustomer(); 를 호출해 고객 목록을 가져오고, 리스트를 모델에 추가하여 뷰return "customer/list"; 로 전달.
  • joinView 메서드 : 회원가입 페이지를 표시하는 요청을 처리. return "customer/join"; 뷰를 반환.
  • joinAction 메서드 : 사용자가 입력한 회원가입 폼 데이터를 처리. customerService.saveCustomer(customer);를 호출해 새 고객을 데이터베이스에 저장 후 return "redirect:/";홈페이지로 리다이렉트.
  • deleteCustomer 메서드 : url 파라미터로 전달된 @RequestParam("customer_seq") int customer_seq를 받아 customerService.deleteCustomer(customer_seq);를 호출해 데이터베이스에서 삭제후 홈페이지로 리다이렉트.

(html 생성) : 뷰는 사용자에게 데이터를 표시하는 부분으로 모델로부터 전달된 데이터를 HTML로 렌더링한다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>회원 리스트</title>
</head>
<body>
	<h1>전체 회원</h1>
	<h3 th:if="${#lists.isEmpty(customers)}">아직 회원가입한 고객이 없습니다.</h3>
	<table border="1" th:unless="${#lists.isEmpty(customers)}">
		<thead>
			<tr>
				<th>회원번호</th>
				<th>아이디</th>
				<th>이름</th>
				<th>가입날짜</th>
				<th>회원탈퇴</th>
			</tr>
		</thead>
		<tbody>
			<tr th:each="customer : ${customers}">
				<td th:text="${customer.customer_seq"></td>
				<td th:text="${customer.id}"></td>
				<td th:text="${customer.name}"></td>
				<td th:text="${#dates.format(customer.regdate, 'yyyy-MM-dd HH:mm')}"></td>
				<td>
					<a th:href="@{/delete(customer_seq=${customer.customer_seq})}">탈퇴</a>
				</td>
			</tr>
		</tbody>
	</table>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>회원가입 페이지</title>
</head>
<body>
	<h1>회원가입</h1>
	<form action="/join" method="post">
		<label for="id">ID : </label>
		<input type="text" id="id" name="id" required><br>
		
		<label for="password">Password : </label>
		<input type="password" id="password" name="password" required><br>
		
		<label for="name">Name : </label>
		<input type="text" id="name" name="name"><br><br>
		
		<button type="submit">회원가입</button>
	</form>
</body>
</html>

 

 

========== 수정 ==========

404 오류 원인.... 패키지를 com.demo의 하위폴더가 아닌 com.controller, com.service, com.domain, com.repository라고 했다....

하위 폴더로 수정

수정 후 localhost:1234/join을 해보자.. 후..

회원가입 페이지

잘 나오네요.... 하;;;

가입날짜가 비어있네요.... 다시 로직을 다시 구현해야.....
아무튼 404 안보여서 다행입니다 하하;;;;