Programming/스프링(spring) - Enterprise

스프링(spring)/ 다듬기 1(MVC에 대한 고찰)

esoog Polaris 2023. 8. 9. 23:23
반응형

<컨트롤러 C>

 

1. 제일 중요한 url 매핑기능 익히기

 

	@GetMapping("/account/join")
	public void getJoin(Model model) throws Exception {
		List<String> countryCodes = null;
		countryCodes = userService.getCountryCodes();
		model.addAttribute("countryCodes", countryCodes);
	}


	@PostMapping("/account/update")
	public String postUpdate(UserVO vo) throws Exception {
		String inputPass = vo.getPwd();
		String pwd = pwdEncoder.encode(inputPass);
		vo.setPwd(pwd);

		userService.memberUpdate(vo);
		return "redirect:/";
	}

* @GetMapping은 페이지 연결을 위한(.jsp기본 로딩 방식은 GET방식이다.)

@PostMapping은 파라미터를 사용하여 데이터를 처리하기 위한.

예외는 처음부터 끝까지 던진다.

 

* 컨트롤러단에서 중각 처리 객체는 List<VO> 를 많이 활용.

파라미터로 Model model을 많이 쓰는데 이는 출력을 위한 파라미터 임.

model.addAttribute("뷰에 넘길 이름", 객체) 처럼 사용.

 

*VO단에서 정리한 데이터 객체의 게터와 세터를 활용.

vo활용을 어떻게 하는지 눈에 익히기.

 

 

 

 

2. 다음 또 중요한 거 의존성 자동 주입(Service단 활용)

 

	@Autowired
	private BoardService service;

 

 

 

 

 

3. 세션 session 사용해서 로그인 구현. 컨트롤러 단에서 중요한 것 같다.

 

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

	@PostMapping("/account/login")
	public String login(UserVO vo, HttpServletRequest req, RedirectAttributes rttr) throws Exception {

		HttpSession session = req.getSession();
		UserVO login = userService.login(vo);

		if (login == null || !pwdEncoder.matches(vo.getPwd(), login.getPwd())) {
			rttr.addFlashAttribute("msg", false);
			return "redirect:/account/login"; // 리다이렉트하여 로그인 페이지로 돌아감
		} else {
			session.setAttribute("member", login);
		}
		// member라는 이름으로 login 객체를 저장함.

		return "redirect:/";
	}

* 로그인 기능은 일단, 데이터베이스에서 회원정보를 찾아서,  일치 확인 후, 결과를 리턴해야 한다.

 

* import javax.servlet.http.HttpSession; 

이걸로 객체 HttpSession session을 만들어서 세션을 저장시킬 수 있다.

 

* import javax.servlet.http.HttpServletRequest;

이녀석이 HTTP에서 서버로 보낸 요청을 처리한다.

.getSession()으로 세션 객체 생성.

.setAttribute("이름", 객체)으로 객체 저장.

.getCookies()으로 쿠키 정보 생성.

 

* import org.springframework.web.servlet.mvc.support.RedirectAttributes;

이녀석은 HTTP로 리다이렉트 할 때, 

.addFlashAttribute("이름", 값)을 바로 전달시킬 수 있음.

 

* return "redirect:/"; 리다이렉트 사용 방법

 

 

 

 

 

<모델 M>

 

1. 작업할 데이터 테이블 생성 후, 컬럼과 객체 매칭 정리 VO

 

package com.project.model;

import java.util.Date;

public class BoardVO {

	private int idx;
	private String title;
	private Date date;

	public int getIdx() {
		return idx;
	}

	public void setIdx(int idx) {
		this.idx = idx;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
}

 * 타입 주의

 

 

 

 

2. 다음으로 DAO와 Service 인터페이스는 똑같이 구성

 

	public List<BoardVO> subject(int sub_idx) throws Exception;
	public void subjectCount(BoardVO vo) throws Exception;

* 이런식으로 객체 선언.

 

 

DAO Impl 구현부를 보면,

 

@Repository
public class BoardDAOImpl implements BoardDAO {

	@Autowired
	private SqlSession sql;

	private static String namespace = "com.project.mappers.board";

	@Override
	public List<BoardVO> debate(int idx, String sender) throws Exception {
		HashMap<String, Object> data = new HashMap<>();
		data.put("sender", sender);
		data.put("idx", idx);
		return sql.selectList(namespace + ".getDebate", data);
	}

* @Repository어노테이션은 주로 데이터 액세스 계층에서 DAO(Data Access Object) 클래스를 나타내는 데 사용
DAO 클래스를 스프링 빈으로 등록하는 데 사용

 

*  DAOImpl 구현부는 데이터베이스와 상호작용하므로 Sql 활용 자동 의존성 주입 객체 사용.

 

* namespace 객체로 매퍼파일 패키지명으로 사용. 매퍼 사용.

 

* sql.의 함수들은 (사용매퍼 함수, 파라미터 1)의 형태로 매개변수를 받음.

그래서 HashMap<String, Object> data = new HashMap<>(); 객체를 생성해서 값을 담아 파라미터로 줌.

data.put("이름",값) 

 

 

ServiceImpl은 DAO로 연결 시켜준다.

 

@Service
public class BoardServiceImpl implements BoardService {

	@Autowired
	private BoardDAO dao;

	@Override
	public List<BoardVO> debate(int idx, String sender) throws Exception {
		return dao.debate(idx, sender);
	}

*@Service 어노테이션은 주로 비즈니스 로직이 구현된 서비스 클래스를 나타내는 데 사용
비즈니스 로직을 처리하는 서비스 계층에서 사용되며, 이러한 클래스를 스프링 빈으로 등록할 때 

 

* 이런식으로 DAO에게 파라미터를 넘겨주는 식이다. 

Service > ServiceImpl > DAO > DAOImpl >

그 다음은

 

 

 

 

3. Mapper가 값을 받아서 쿼리문을 실행시킨다. (MyBatis)

 

	<!-- 셀렉트 -->
	<select id="list" resultType="com.project.model.BoardVO">
		select
		*
		from board
		WHERE
		sub_idx=#{sub_idx}
		ORDER BY date DESC
	</select>


	<!-- 업데이트 -->
	<update id="clickNum" parameterType="com.project.model.BoardVO">
		update board
		set
		hcount =
		hcount + 1
		where idx= #{idx}
	</update>
    
    
    <!-- 인서트 -->
	<insert id="write" parameterType="com.project.model.BoardVO">
		insert into
		board(title, text,
		nick, sub_idx)
		values(#{title}, #{text},
		#{nick}, #{sub_idx})
	</insert>
    
    
    <!-- 델리트 -->
    <delete id="delete" parameterType="com.project.model.BoardVO">
		delete
		from board
		where idx=
		#{idx}
	</delete>
    
    
    <!-- 검색 -->
	<select id="search" parameterType="hashMap"
		resultType="com.project.model.BoardVO">
		SELECT *
		FROM board
		WHERE
		title LIKE CONCAT('%', #{keyword},
		'%')
		OR text LIKE CONCAT('%',
		#{keyword}, '%')
		OR nick LIKE CONCAT('%',
		#{keyword}, '%')
		ORDER BY idx DESC
	</select>

*일반 쿼리문 작성 문법이다.

여기서 id가 DAOImpl에서 접근하는 함수 이름이다.

 

* 값을 주기만 하면 되는 update, insert, delete

정보를 받아와야 하는 거는 select 정도 기억.

 

* 마지막 검색 구현이 조금 까다롭다.

parameterType="hashMap" resultType="com.project.model.BoardVO" 를 사용해서

해쉬맵에 담긴 객체를 활용해서 파라미터로 검색하고,

결과를 객체 형태로 출력 시킨다.

컬럼 LIKE CONCAT('%', #{keyword}, '%') 이런 형식으로 해야 %를 키워드로 인식한다.

나머지는 기본 쿼리문을 공부해두는 게 좋을 듯 하다.

 

그럼 전체 방향은. Controller에서 출발해서

> Service > ServiceImpl > DAO > DAOImpl > Mapper >

이 결과가 다시 Controller로 돌아와서 마지막으로 뷰 V 로 간다.

 

 

 

 

<뷰 V>

 

1. 기본 JSP파일 상단 필수구문.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>
<html lang="ko">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="stylesheet" href="../../resources/home.css">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css">
<script src="https://code.jquery.com/jquery-latest.min.js"></script>

<title>안녕하세요</title>
</head>

*부트스트랩 버전이 3.4.1이 마음에 들어서 택했다.

Jquery는 최신으로 계속 쓸 수 있다.

 

 

 

 

2. JSP JSTL 세션 활용

 

<c:set var="member" value="${sessionScope.member}" />
<!-- 세션스코프는 서블릿에서 제공하는 스코프 중 하나인데 서블릿에서 이미 저장되어 있다. -->
<c:if test="${not empty member}">
    <p class="userLog">${member.id}님환영합니다.</p>
</c:if>


<c:if test="${msg == false}">
    <script>
        $(document).ready(function() {
            alert("아이디와 비밀번호 확인해주세요.");
        });
    </script>
</c:if>


<c:forEach items="${nest}" var="nest">
    <c:if test="${nest.date==nestDebate.max_date}">
        <div class="text">최근대화: ${nest.text}</div>
    </c:if>
</c:forEach>

* 위에서 <c:set var="member" value="${sessionScope.member}"/>로 지정했는데;

이미 세션저장을 member로 해놔서 다시 세팅을 안하고 사용할 수 있음.

${member}

 

*<c:if test="조건"></c:if> 로 사용

안에서 바로 스크립트를 사용할 수 있다.

 

*<c:forEach items="데이터묶음" var="이름">

    이름

</c:forEach>

처럼 for문을 사용해서 데이터묶음에서 이름으로 하나씩 꺼내서 사용할 수 있다.

이름안에 다른 객체를 품고 있다면, 이름.객체

 

 

 

 

3. HTML에서 많이 쓰이고 중요한 것들

 

<div id="idx" data-value="${originListIdx}"></div>


<div class="content" onclick="location.reload('/board/debateNest?idx=${mine.idx}');">


<input type="hidden" name="title" value="${subject.title}">


<button class="btn btn-success" type="submit" id="submit">회원가입</button>
<button class="cancle btn btn-danger" type="button">취소</button>


<textarea class="form-control" id="tArea" rows="15" name="text"></textarea>

*html div태그 안 data-이름="" 은 자바스크립트로 보낼 데이터 벨류를 넣을 수 있다.

data-abc="def"

 

*div 요소 중 onclick="location.reload('/');" 는 div 요소로서 클릭시. 자바스크립트 함수처럼 실행.

 

*input type="hidden" 요소 속성은 form태그에서 데이터 처리 할 때, 보이지 않게 넘기는 방식.

 

*buttom type="submit"은 form태그 안에서 input요소 처리

="button"은 단순히 버튼효과로 자바스크립트에서 처리

 

*<textarea rows="15" >는 줄 높이를 조절하여 텍스트 박스를 만듦.

 

 

 

 

 

4. 자바스크립트와 jQuery에서 많이 쓰이고 중요한 것들

 

<script>
    alert("로그인을 해야 작성이 가능합니다.");
    location.href = '/'; // 여기서 '/페이지'는 이동하고자 하는 페이지의 URL입니다.


    $("#submit").on("click", function() {
        var text = $("#tArea").val().trim();
        if (text.length == 0) {
            alert("내용을 입력해 주세요");
            $("#tArea").focus();
            return false;
        }
    });


    $("#senderGood").on("click", function() {
        $.ajax({
            type : "POST", // 요청 메소드
            url : "/board/debate3", // 요청 보낼 URL
            data : {
                channel : channel,
                senderGood : 1,
                senderBad : 0,
                receiverGood : 0,
                receiverBad : 0,
                debateGood : 0,
                debateBad : 0
            }, // 보낼 데이터 (필요에 따라 수정)
            success : function(response) {
                location.reload(); // 페이지 리로드
            },
            error : function(xhr, status, error) {
                // 요청 실패 시 실행할 코드
            }
        });
    });
    
    $("#logoutBtn").on("click", function () {
        // 로그아웃 버튼 클릭 시 확인 창 띄우기
        if (confirm("로그아웃하시겠습니까?")) {
            // 확인 버튼을 누르면 /logout 경로로 POST 요청을 보냄
            $.post("/logout", function (data) {
                // 로그아웃 성공 시 홈으로 리다이렉트
                location.href = "/";
            }).fail(function () {
                // 로그아웃 실패 시 에러 메시지를 표시할 수 있음
                alert("로그아웃 실패!");
            });
        }
    });

</script>

*alert();는 경고창 띄움

location.href = '/'; 링크 페이지로 이동

 

*자바스크립트부는 태그의 id속성 값을 사용한다. "#id이름" 쌍따옴표 사용 주의.

클릭이벤트가 자주 쓰이는데 이런 방식이다.

 $("#id").on("click", function() {

    실행부

    }

});

 

* AJAX 기본 사용법.

$.ajax({

    type: 'POST', 또는 'GET'

    url: '/', 

    data: {

        키:값, 키:값...

    }

    success: function(responseData) {

        console.log(responseData);

     },

    error: function(xhr, status, error) { 

        console.error('AJAX 요청 실패:', status, error);

    }

});

 

* 로그인 로그아웃 관련은 보안을 위해서 무조건 POST방식으로 사용한다.

 

지금까지 이렇게 흘러왔다.

 

(이전에 데이터베이스 구축, VO 정리)

V(get요청,post요청) >

    Controller >

        (M)Service > ServiceImpl > DAO > DAOImpl > Mapper >

    Controller  >

V

 

그리고 우리는 이제 멋진 하나의 웹을 본다.

728x90