데이터융합 JAVA응용 SW개발자 기업 채용연계 연수과정 62일차 강의 정리

misung·2022년 6월 24일
0

Spring

MyBatis

게시판 만들기 실습 (이어서)

[BoardMapperTest] 클래스, [BoardMapper] xml 수정

BoardMapperTest.java

//게시글 등록 단위 테스트
	@Test
	public void insertTest() {
		for(int i=1; i<=323; i++) {
			BoardVO article = new BoardVO();
			article.setTitle("테스트 제목입니다." + i);
			article.setWriter("김테스트" + i);
			article.setContent("테스트 중이니까 조용히 하세요!" + i);
			mapper.insert(article);
		}
	}

게시글 VO를 323번까지 상기한 내용으로 쭉 채운다.
이제 insert() 작업을 수행해야 하니 Mapper XML에 작업을 할 수 있도록 수정하자.

BoardMapper.xml

<insert id="insert">
		INSERT INTO mvc_board
		(board_no, title, content, writer)
		VALUES(board_seq.NEXTVAL,#{title},#{content},#{writer})
</insert>

mvc_board 에 컬럼명을 지정하고, 게시물 번호같은 경우에는 미리 만들어둔 시퀀스를 이용하고, 나머지는 VO 의 컬럼명을 써 넣는다.

테스트 진행

테스트 진행 시에는 우측의 Outline 창을 열고, 테스트하려는 메서드 이름을 우클릭하여 Run As - JUnit Test를 선택해서 테스트를 진행하면 된다.

그리고 DB에 SELECT * FROM mvc_board 쿼리를 날려 확인한 결과, 잘 들어간 것을 확인할 수 있었다.

[BoardMapperTest] 클래스, [BoardMapper] XML파일 여러가지 테스트 진행

BoardMapperTest.java

package com.spring.mvc.board;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.spring.mvc.board.model.BoardVO;
import com.spring.mvc.board.repository.IBoardMapper;

@RunWith(SpringJUnit4ClassRunner.class)
//테스트 환경에서 Mapper 객체 활용을 위해 빈 등록 설정이 있는 xml 파일을 로딩.
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/mvc-config.xml"})
public class BoardMapperTest {

	@Autowired
	private IBoardMapper mapper;

	//게시글 등록 단위 테스트
	@Test
	public void insertTest() {
		for(int i=1; i<=323; i++) {
			BoardVO article = new BoardVO();
			article.setTitle("테스트 제목입니다." + i);
			article.setWriter("김테스트" + i);
			article.setContent("테스트 중이니까 조용히 하세요!" + i);
			mapper.insert(article);
		}
	}

	//게시글 목록 전체 조회 테스트
	//게시물 개수 몇개인지 출력하시고, 게시글 모든 내용을 toString()으로 출력하세요.
	@Test
	public void getListTest() {
		List<BoardVO> list = mapper.getArticleList();
		System.out.println("게시물 개수: " + list.size());
		for(BoardVO vo : list) {
			System.out.println(vo);
		}
	}

	//게시글 단일 조회 테스트
	//44번글을 조회해서 글 상세 내용을 출력해 주세요.
	@Test
	public void getArticleTest() {
		BoardVO vo = mapper.getArticle(44);
		System.out.println(vo);
	}

	//게시글 수정 테스트
	//BoardVO 객체를 하나 생성하시고, VO의 setter를 사용하여
	//수정 내용(글 제목, 글 내용)을 입력하고 수정을 진행해 보세요. (1번글의 제목, 내용)
	@Test
	public void updateTest() {
		BoardVO vo = new BoardVO();
		vo.setBoardNo(1);
		vo.setTitle("수정된 제목 수정수정");
		vo.setContent("수정입니다. 수정이에요. 내용 수정수정");
		mapper.update(vo);
		System.out.println("수정 후 정보: " + mapper.getArticle(1));
	}

	//게시글 삭제 테스트
	//3번글을 삭제하세요. 삭제 후 상세보기를 통해 3번글을 가져왔을 때 null이 리턴되는지
	//조건문으로 확인해서 결과를 출력하세요. (null이 왔다는것 -> 삭제 성공! 게시글 없음!)
	@Test
	public void deleteTest() {
		mapper.delete(3);
		if(mapper.getArticle(3) == null) {
			System.out.println("삭제 성공! 게시물 없음!");
		} else {
			System.out.println("삭제 실패 ㅠㅠ");
		}
	}

}

각종 테스트를 지시받고 테스트를 위한 메서드를 작성했다.
그리고 메서드마다 실행할 쿼리문을 Mapper.xml에다 만들어줘야 한다.

BoardMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
<mapper namespace="com.spring.mvc.board.repository.IBoardMapper">

	<resultMap type="com.spring.mvc.board.model.BoardVO" id="BoardMap">
		<id property="boardNo" column="board_no" />
		<result property="regDate" column="reg_date" />
		<result property="viewCnt" column="view_cnt" />
	</resultMap>

	<insert id="insert">
		INSERT INTO mvc_board
		(board_no, title, content, writer)
		VALUES(board_seq.NEXTVAL,#{title},#{content},#{writer})
	</insert>
	
	<select id="getArticleList" resultMap="BoardMap">
		SELECT * FROM mvc_board
		ORDER BY board_no DESC
	</select>
	
	<select id="getArticle" resultMap="BoardMap">
		SELECT * FROM mvc_board
		WHERE board_no=#{boardNo}
	</select>
	
	<update id="update">
		UPDATE mvc_board
		SET title=#{title}, content=#{content}
		WHERE board_no=#{boardNo}
	</update>
	
	<delete id="delete">
		DELETE FROM mvc_board
		WHERE board_no=#{boardNo}
	</delete>

</mapper>

[IBoardService], [BoardService] 클래스 생성

com.spring.mvc.board 하위에 service 패키지를 만들고 그 안에 생성.

IBoardService.java

package com.spring.mvc.board.service;

import java.util.List;

import com.spring.mvc.board.model.BoardVO;

public interface IBoardService {
	
	//게시글 등록 기능
	void insert(BoardVO article);
	
	//게시글 전체 조회 기능(페이징 전)
	List<BoardVO> getArticleList();
	
	//게시글 상세 조회 기능
	BoardVO getArticle(int boardNo);
	
	//게시글 수정 기능
	void update(BoardVO article);
	
	//게시글 삭제 기능
	void delete(int boardNo);
	
	//게시글 수 조회 기능


}

기본적으로 서비스에서 구현해야 할 메서드를 정의해 두었음.

BoardService.java

package com.spring.mvc.board.service;

import java.util.List;

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

import com.spring.mvc.board.model.BoardVO;
import com.spring.mvc.board.repository.IBoardMapper;

@Service
public class BoardService implements IBoardService {
	
	@Autowired
	private IBoardMapper mapper;

	@Override
	public void insert(BoardVO article) {
		mapper.insert(article);
	}

	@Override
	public List<BoardVO> getArticleList() {
		return mapper.getArticleList();
	}

	@Override
	public BoardVO getArticle(int boardNo) {
		return mapper.getArticle(boardNo);
	}

	@Override
	public void update(BoardVO article) {
		mapper.update(article);
	}

	@Override
	public void delete(int boardNo) {
		mapper.delete(boardNo);
	}

}

이전같았다면 DAO를 호출해서 DAO에서 작업을 이어가야 했지만, MyBatis 덕분에 서비스 클래스에서 매퍼를 호출하기만 하면 되는 간단한 구조가 되었다.

[BoardController] 및 [BoardControllerTest] 클래스 생성

BoardController.java

package com.spring.mvc.board.controller;

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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.spring.mvc.board.model.BoardVO;
import com.spring.mvc.board.service.IBoardService;

@Controller
@RequestMapping("/board")
public class BoardController {

	@Autowired
	private IBoardService service;
	
	//게시글 전체 목록 불러오기 요청
	@GetMapping("/list")
	public String list(Model model) {
		System.out.println("/board/list: GET");
		model.addAttribute("articles", service.getArticleList());
		
		return "board/list";
	}

	//글쓰기 페이지로 이동 요청
	@GetMapping("/write")
	public void write() {
		System.out.println("/board/write: GET");
	}
	
	//게시글 DB 등록 요청
	@PostMapping("/write")
	public String write(BoardVO article) {
		System.out.println("/board/write: POST");
		service.insert(article);
		
		return "redirect:/board/list";
	}
	
	//게시글 상세보기 요청
	@GetMapping("/content/{boardNo}")
	//@PathVariable은 URL 경로에 변수를 포함시켜 주는 방식
	//null이나 공백이 들어갈 수 있는 파라미터라면 적용하지 않는 것을 추천.
	//파라미터 값에 .이 포함되어 있다면 .뒤의 값은 잘린다는 걸 알아두세요.
	//{}안에 변수명을 지어주시고, @PathVariable 괄호 안에 영역을 지목해서
	//값을 받아옵니다.
	public String content(@PathVariable int boardNo, Model model) {
		System.out.println("/board/content: GET");
		System.out.println("요청된 글 번호: " + boardNo);
		model.addAttribute("article", service.getArticle(boardNo));
		return "board/content";
	}
	
	//게시글 수정 처리 요청
	@PostMapping("/modify")
	public String modify(BoardVO article) {
		System.out.println("/board/modify: POST");
		service.update(article);
		
		return "redirect:/board/content?boardNo=" + article.getBoardNo();
	}
	
	//게시글 삭제 처리 요청
	@PostMapping("/delete")
	public String remove(int boardNo,
						RedirectAttributes ra) {
		System.out.println("/board/delete: POST");
		service.delete(boardNo);
		ra.addFlashAttribute("msg", "delSuccess");
		
		return "redirect:/board/list";
	}
	
	
}

사용자 뷰(페이지) 에서 넘어오는 GET 또는 POST 요청에 따라 알맞게 처리를 해 준다.

@PathVariable 이거 뭐지?

BoardControllerTest.java

package com.spring.mvc.board;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import lombok.extern.log4j.Log4j;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/mvc-config.xml",
"file:src/main/webapp/WEB-INF/spring/servlet-config.xml"})
@WebAppConfiguration
@Log4j
public class BoardControllerTest {

	/*
	 - 테스트 환경에서 가상의 DispatcherServlet을 사용하기 위한 객체 자동 주입.
	 - WebApplicationContext는 Spring에서 제공되는 servlet들을 사용할 수 있도록
	 정보를 저장하는 객체입니다.
	 */
	@Autowired
	private WebApplicationContext ctx;

	//	@Autowired
	//	private BoardController controller;

	//MockMvc는 웹 어플리케이션을 서버에 배포하지 않아도 스프링 MVC 동작을
	//구현할 수 있는 가상의 구조를 만들어 줍니다.
	private MockMvc mockMvc;

	@Before
	public void setUp() {
		//가상 구조를 세팅
		//스프링 컨테이너에 등록된 모든 빈과 의존성 주입까지 로드해서 사용이 가능.
		this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();

		//테스트할 컨트롤러를 수동으로 주입. 하나의 컨트롤러만 테스트를 진행할 때 이렇게 씁니다.
		//this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
	}

	@Test
	public void testList() throws Exception {
		log.info(
				mockMvc.perform(MockMvcRequestBuilders.get("/board/list"))
				.andReturn()
				.getModelAndView()
				.getModelMap()
				);
	}

	@Test
	public void testInsert() throws Exception {
		String viewPage = mockMvc.perform(MockMvcRequestBuilders.post("/board/write")
				.param("title", "테스트 새 글 제목")
				.param("content", "테스트 새 글 내용")
				.param("writer", "user01")
				).andReturn().getModelAndView().getViewName();

		log.info(viewPage);
	}

	//게시글 상세보기 요청 넣어보기.
	//컨트롤러에서는 DB에서 가지고 온 글 객체를 model에 담아서 jsp로 이동시킬 것입니다.
	//42번글을 보여달라는 요청을 넣으시고, 요청 결과가 들어있는 model을 출력해 보세요.
	// /board/content -> get
	@Test
	public void testContent() throws Exception {
		log.info(
				mockMvc.perform(MockMvcRequestBuilders.get("/board/content")
						.param("boardNo", "33")
						).andReturn().getModelAndView().getModelMap()
				);
	}


	//5번글의 제목과 내용을 수정하는 요청을 보낼 예정입니다.
	//전송방식은 post 방식입니다.
	//수정 후 이동하는 페이지는 해당 글의 상세보기 페이지입니다.
	//컨트롤러가 리턴하는 viewName을 출력해 주세요. ("/board/modify")
	@Test
	public void testModify() throws Exception {
		log.info(
				mockMvc.perform(MockMvcRequestBuilders.post("/board/modify")
						.param("title", "수정된 테스트 글 제목 2")
						.param("content", "수정된 테스트 글 내용2")
						.param("boardNo", "5")
						).andReturn().getModelAndView().getViewName()
				);
	}


	//42번글을 삭제하세요.
	//전송 방식은 post방식이고, 이동하는 곳은 목록 요청이 재요청될 것입니다.
	//viewName을 출력해 주세요.
	@Test
	public void testRemove() throws Exception {
		log.info(mockMvc.perform(MockMvcRequestBuilders.post("/board/delete")
				.param("boardNo", "42")
				).andReturn().getModelAndView().getViewName()
				);
	}
}

세부 설명을 하자면..

@RunWith(SpringJUnit4ClassRunner.class)

이 객체를 통해서 실행을 하겠다는 뜻

@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/mvc-config.xml",
"file:src/main/webapp/WEB-INF/spring/servlet-config.xml"})

설정 가져오기. servlet-config 는 왜 가져오냐? 하면, 컨트롤러 설정은 servlet-config 에 들어있기 때문!!

@WebAppConfiguration

조금 밑의 private WebApplicationContext ctx; 을 주입하기 위해서 이 어노테이션을 선언해두어야 한다.

@Log4j

lombok에서 지원하는 라이브러리.

아까 게시글 단위로 추가, 수정, 삭제 시와 다르게 뭔가 메서드가 더 붙어있거나, 멤버변수가 더 있는데,

왜냐하면 지금 하려는 테스트들은 서버가 동작하는 상황에서의 테스트를, 서버를 안 켜고 서버 동작을 가상으로 흉내내어 테스트하기 위함이다.

testList() 메서드
@Test
	public void testList() throws Exception {
		log.info(
				mockMvc.perform(MockMvcRequestBuilders.get("/board/list"))
				.andReturn()
				.getModelAndView()
				.getModelMap()
				);
	}

.perform() - 요청 넣는 메서드
.andReturn() - 반환값 체크
.getModelAndView() - 요청 받은 것에서 Model과 View 꺼내기
.getModelMap - 그리고 거기서 모델 맵을 꺼냄 (뷰는 냅두고, 모델만 꺼냄) (밑에 다른 메서드 보다 안건데, 그냥 GetModel() 뭐 이런 이름의 메서드라고 보면 되는듯.)

INFO : com.spring.mvc.board.BoardControllerTest - {articles=[BoardVO(boardNo=323, title=테스트 제목입니다.323, content=테스트 중이니까 조용히 하세요!323, writer=김테스트323, ...

testList() 메서드를 호출한 뒤의 결과인데, 모든 게시글 (323개) 에 대해 결과값을 반환하고 있으므로 일부만 나오게 결과를 잘랐다.

testInsert() 메서드
@Test
	public void testInsert() throws Exception {
		String viewPage = mockMvc.perform(MockMvcRequestBuilders.post("/board/write")
				.param("title", "테스트 새 글 제목")
				.param("content", "테스트 새 글 내용")
				.param("writer", "user01")
				).andReturn().getModelAndView().getViewName();

		log.info(viewPage);
	}

.param() - 나중에는 <form> 태그에서 입력된 내용을 넘겨주겠지만, 지금은 서버 없이 Mock으로 테스트중이므로 param() 메서드를 사용해서 값을 대입해준다.

BootStrap 으로 구성된 화면 기반 프로젝트

  1. 카톡으로 제공받은 소스 다운로드
  2. webapp - resources 하위에 붙여넣기

처음 소스를 제공받고 프로젝트에 우클릭하여 Run As - Server 선택하여 실행하면 제대로 실행이 되지 않을 것임.

무수히 많은 404 에러 해결하기

푸터는 별 게 없고, 헤더는

<!-- Bootstrap core CSS -->
  <link rel="stylesheet" href="<c:url value='/vendor/bootstrap/css/bootstrap.min.css'/>">

이렇게 CSS 위치를 참조하고 있다. 단, 디렉토리 상에 /resources 디렉토리가 하나 더 껴져 있어서, 인식하지 못하고 있는 상태이다.

그렇다고 해서 모든 참조에 /resources 를 넣어줄 순 없으므로, 다음과 같은 방법으로 해결한다.

servlet-config.xml

<!-- 정적 자원(html, css, js, img...)등을 URI 절대 경로로 사용하기 위한 매핑 처리 -->
	<!-- mapping: 사용자에게 노출되는 경로, location: 실제 파일의 경로 -->
	<resources mapping="/resources/**" location="/resources/" />
	<resources mapping="/css/**" location="/resources/css/" />
	<resources mapping="/js/**" location="/resources/js/" />
	<resources mapping="/img/**" location="/resources/img/" />
	<resources mapping="/scss/**" location="/resources/scss/" />
	<resources mapping="/vendor/**" location="/resources/vendor/" />

먼저 /resources 에 대한 주소 매핑 처리를 하고, 나머지 5개의 디렉토리에 대해서도 매핑을 해 둔다.

여기까지 하고 Run As - Server 을 다시 해 보면 잘 실행이 될 것이다.

외부 노출 경로 수정

잘 켜졌다 한들, 페이지 소스 보기를 하면 페이지가 /mvc/vendor ... 이렇게 연결되어있는 것을 확인할 수 있다.

실제로는 src/main/resources 순으로 접근하고 있기 때문에 이것을 수정하려면 Servers - Tomcat V9.0 - server.xml 을 연다.

맨 아래로 쭉 내려서,

<Context docBase="SpringDBAccess" path="/db" reloadable="true" source="org.eclipse.jst.jee.server:SpringDBAccess"/><Context docBase="SpringWebMvcProject" path="/" reloadable="true" source="org.eclipse.jst.jee.server:SpringWebMvcProject"/>

이 부분 중에 path 속성이 /mvc 로 되어있었을 텐데, / 만 남기고 다 지워서 위와 같게 한다.

그리고 주의! Run on Server를 다시 하는데, 뭔가 팝업이 뜨면 NO 를 누른다.

그리고 나서 브라우저에 뜬 프로젝트를 보면 주소가 깔끔하게 정리된 것을 확인할 수 있다.

URL에서 포트번호 삭제하고 ip만 남기기

  1. STS 또는 이클립스 좌하단의 Servers 에서 Tomcat 서버 더블 클릭

  2. 뜬 Overview 창에서 우측 Ports 속성 중, HTTP/1.1의 포트넘버를 80번으로 변경

HTTP 표준 포트번호가 80번이라, 브라우저에서 포트번호를 생략하고 ip주소만 남겨 표시해주게 된다.

다른 페이지로의 연결 복구해주기

아마 이 상태에서 페이지의 이곳 저곳을 눌러보면 404 에러가 뜨는 경우가 있을 것이다. 페이지 자체는 존재하긴 하는데 컨트롤러에서 요청 처리를 해주는 메서드가 없어서 발생하는 에러가 대부분이므로, 관련 에러를 하나씩 해결해 나가보자.

HomeController.java 수정

HomeController.java

...
@GetMapping("/introduce")
	public String intro() {
		return "introduce/introduce";
}

메인 페이지로의 요청에 대한 응답을 만들어준다.

header.jsp 수정
...
<li class="nav-item">
            <a class="nav-link js-scroll-trigger" href="<c:url value='/board/list' />">BOARD</a>
</li>
...

상단 네비게이션 바에서 BOARD 라고 써진 부분을 눌러도 아무 반응이 없었을텐데, 당연히 이동이 되게 만들어져있지 않았으므로 <c:url> jstl로 루트 컨텍스트를 잡아주고 value 에 나머지 주소를 넣어둔다.

list.jsp 수정
<!-- 게시물이 들어갈 공간 -->
						<c:forEach var="b" items="${articles}">
							<tr style="color: #643691;">
								<td>${b.boardNo}</td>
								<td>${b.writer}</td>

								<td>
									<a style="margin-top: 0; height: 40px; color: orange;" href="<c:url value='/board/content/${b.boardNo}' />">
										${b.title}
									</a>
								</td>

								<td>${b.regDate}</td>
								<td>${b.viewCnt}</td>
							</tr>
						</c:forEach>

게시물을 표시하면 되는데, 원래 각 부분이 비워져있었고 이 부분을 채우면 된다.

<div class="col-sm-2">
							<a href="<c:url value='/board/write' />" class="btn btn-cpp float-right">글쓰기</a>
						</div>

그리고 밑에 글쓰기 부분이 비워져 있었는데 여기도 글쓰기 요청을 보내도록 만들어 준다.

BoardController 에 글쓰기 페이지 이동 요청 처리받는 메서드 만들기
...
//글쓰기 페이지로 이동 요청
	@GetMapping("/write")
	public void write() {
		System.out.println("/board/write: GET");
	}
...
그 외 진행
  • write.jsp 페이지에서 글 등록 버튼 누르면 요청 보내게 만들고, 컨트롤러에서 받도록 하게 해 두기
  • content.jsp 페이지에서 각 <form> 내의 작성자, 제목, 내용 등을 ${article.writer}, ${article.title}, {$article.content} 등으로 표기시키게 하기.
  • list.jsp 페이지에서 <title> 태그 내의 href= 속성을 보면, /board/content/boardNo?=${b.boardNo} 로 표기되어 있었는데, 이걸 /board/content/${b.boardNo} 로 수정.

근데 이렇게 다이렉트로 때려박으면 처리가 될 리가 없음
따라서 추가적인 처리를 했는데,

BoardController 클래스에서 다음과 같은 처리를 해줌.

//게시글 상세보기 요청
	@GetMapping("/content/{boardNo}")
	//@PathVariable은 URL 경로에 변수를 포함시켜 주는 방식
	//null이나 공백이 들어갈 수 있는 파라미터라면 적용하지 않는 것을 추천.
	//파라미터 값에 .이 포함되어 있다면 .뒤의 값은 잘린다는 걸 알아두세요.
	//{}안에 변수명을 지어주시고, @PathVariable 괄호 안에 영역을 지목해서
	//값을 받아옵니다.
	public String content(@PathVariable int boardNo, Model model) {

엉? {boardNo} 로 처리하는건 그렇다 치고, 굳이 @PathVariable 을 넣어야 하는 거야? 라는 생각이 들었는데 그렇다. 넣어야 한다.

왜냐하면 {} 대괄호로 처리된 주소 매핑의 경우 기존처럼 DB 컬럼과 VO 변수 이름이 매칭된다고 해서 자동으로 들어가지 않으므로, @PathVariable 어노테이션을 붙여주어야 한다.

JQuery

과거엔 한 시대를 풍미했지만 이젠 점점 안 쓰는 추세.
그러나 취업 시 개발보단 유지보수를 할 확률이 높고 (신입), 그 사이트들의 대부분은 제이쿼리로 만들어져있을 가능성이 높음.

제이쿼리 도입

  1. https://jquery.com/download/ 접속
  2. Download the compressed, production jQuery 3.6.0 에 우클릭 후 다른 이름으로 저장
  3. /resources/vendor/jquery 에 배치하면 됨.

하지만 우리가 강사님께 배포받은 프로젝트에는 이미 JQuery가 들어있으니 따로 추가 설정할 필요는 없음.

제이쿼리 VSCode에 도입

  1. VSCode 기동
  2. 상단 메뉴에서 파일 - 작업 영역에 폴더 추가 - JQuery 폴더 새로 만들고 영역 추가
  3. 만들어진 JQuery 작업영역 하위에, VSCode 상에서 폴더에 + 기호가 붙은 아이콘을 눌러서 lib 라는 폴더 생성.
  4. 거기에 jquery-3.6.9.min.js 를 넣는다.

제이쿼리 실습 (VSCode)

  1. 이제 JQuery/jquery01.html을 생성하고 실습
  2. html 기본 틀 생성 (! 쓰고 자동완성)
<!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">
    <title>Document</title>

    <script src="lib/jquery-3.6.0.min.js"></script>
</head>
<body>
    <input type="text" id="apple" value="사과">
    <input type="text" class="melon" value="멜론">
    <input type="hidden" value="망고">

    <script>
        const $a1 = document.getElementById('apple');
        const $a2 = $('#apple');
        console.log($a1);
        console.log($a2);

        const b1 = document.querySelector('.melon').value;
        const b2 = $('.melon').val();
        console.log(b1);
        console.log(b2);

        const c1 = document.querySelector('input[type=hidden]').value;
        const c2 = $('input[type=hidden]').val();
        console.log(c1);
        console.log(c2);
    </script>
</body>
</html>

1번들이 바닐라 자바스크립트, 2번들이 JQuery에 의해 단축된 코드들이다.
둘 다 똑같은 결과를 가져오는 걸 알 수 있고, a2의 경우 출력이 좀 a1과는 다른 것처럼 보일 텐데,
가져온 결과를 보여주는 보습만 살짝 달라서 그런지 내용 자체는 같다.

오늘 강의는 여기까지.

0개의 댓글