<컨트롤러 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
그리고 우리는 이제 멋진 하나의 웹을 본다.
'Programming > 스프링(spring) - Enterprise' 카테고리의 다른 글
스프링(spring)/ 스프링부트(springBoot)-mysql연동 (0) | 2023.08.15 |
---|---|
스프링(spring)/ 스프링부트(Spring Boot) 프로젝트 생성 (0) | 2023.08.15 |
스프링(spring)/ +더하기 6(게시판별 좋아요 시스템 구현) (0) | 2023.08.08 |
스프링(spring)/ +더하기 5(관전 시스템) (0) | 2023.08.07 |
스프링(spring)/ +더하기 4(1:1게시판 시스템) (0) | 2023.08.07 |