D+49::ajax문법/스프링부트_학생관리페이지만들기

Am.Vinch·2022년 9월 1일
0

20220902_FRI

ajax(아작스,에이작스)

자바스크립트의 라이브러리.
비동기 통신(서로 데이터를 주고 받는 것)을 가능하게 해 줌.

  • 동기 통신(지금까지 해온 것)
    : 데이터를 주고 받는 시간이 같다.일련의 순서대로 진행이 된다.
    : 화면 -> 컨트롤러(자바) -> 화면 ..(실행의 흐름)
    : 페이지 이동해야 데이터를 보여줄 수 있어서, 상대적으로 부하가 생기고 느릴 수 밖에 없다.
  • 비동기 통신(ajax)
    :화면 -> 컨트롤러 (페이지이동없이 이대로 끝)
    :하나의 페이지에서만 보이기 때문에 페이지 이동없고 데이터를 로딩할 필요가 없어서 성능도 빨라지고 화면의 움직임이 부드럽게 보인다.
  • AjaxTest 스프링 프로젝트 생성

  • application.properties (기본 세팅 설정)

# PORT 포트
server.port=8081

# thymeleaf 캐쉬 설정
spring.thymeleaf.cache=false

#spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
#spring.datasource.url=jdbc:oracle:thin:@127.0.0.1:1521/xe
spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:oracle:thin:@localhost:1521/xe
spring.datasource.username=MYDB
spring.datasource.password=ORACLE

#xml location
#mybatis.mapper-locations=classpath:mappers/**/*.xml
mybatis.mapper-locations=classpath:mappers/*.xml
  • AjaxController 클래스 파일 생성
  • 패키지명:kh.study.ajax.controller
  • 클래스명:AjaxController
  • @RestController 사용하여 경로설정시 html파일생성 별도로 필요없이 바로 리턴값 출력된다.
package kh.study.ajax.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import kh.study.ajax.vo.MemberVO;

@Controller
@RequestMapping("/ajax")
public class AjaxController {
	
	@GetMapping("/ex1") //localhost:8081/ajax/ex1
	public String test1() {
		
		return "ex1";//페이지이동
	}
	
	//@ResponseBody 이 붙은 메소드는 실행 후 페이지이동하지 않는다!
	//return에 이동할 페이지명을 작성하는게 아니라,필요한 데이터를 리턴하면 된다.
	@ResponseBody
	@PostMapping("/ex2") //localhost:8081/ajax/ex1
	public List<MemberVO> test2() {
		System.out.println("test2() 메소드 실행 된다.");
		
		List<MemberVO> list = new ArrayList<>();
		
		MemberVO vo1 = new MemberVO();
		vo1.setName("김자바");
		vo1.setAge(21);
		vo1.setTell("010-1111-2221");

		MemberVO vo2 = new MemberVO();
		vo2.setName("이자바");
		vo2.setAge(22);
		vo2.setTell("010-1111-2222");
		
		MemberVO vo3 = new MemberVO();
		vo3.setName("박자바");
		vo3.setAge(23);
		vo3.setTell("010-1111-2223");
		
		list.add(vo1);
		list.add(vo2);
		list.add(vo3);
		
		//페이지이동하지않고 다시 자바스크립트 ajax_test.js로 가는데,이 리턴값은 result가 가져간다.
		//return "hello";//String 일때
		//return 100;//int 일때
		//return vo;//MemberVO 자료형일때 객체리턴
		return list;//객체리턴
	}
	@ResponseBody
	@PostMapping("/ex3")
	public void test3(MemberVO memberVO, String name, int age) {
		//ajax에서 넘어어오는데이터랑 똑같이 
		//매개변수 membervo나 String name,int age로도 받아올수있다
		System.out.println(memberVO.getAge());//20
		System.out.println(memberVO.getName());//HongJava
	}

}

  • 주소창 localhost:8081 입력시 , return 값 test 화면 출력된다.
  • MemberVo
package kh.study.ajax.vo;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class MemberVO {
	private String name;
	private int age;
	private String tell;
}
  • ex1.html

    Jquery문법 로딩

    :jqury문법 로딩_ 먼저,ajax 스크립트문법 파일만든후, 제이쿼리로 자바스크립트 사용해야 가능하다
    단, 순서가 중요하다! 문법로딩을 가장 먼저 사용 후, 뒤에 자바스크립트 코드를 사용가능하다!
    <script src="https://code.jquery.com/jquery-latest.min.js"></script>

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"><!-- jsp에서 foreach문 사용할때 lib태그 사용하는 것과 같다.앞으로 html 만들때는 사용해야한다. 원래 html만들때 next누르고 별도로 생성한 htnl_thymeleaf를 선택하면 자동생성된다-->
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
ex1<br>
<input type="button" value="실행1" onclick="test1();">
<input type="button" value="실행2" onclick="test2();">

<!--jqury문법 로딩: ajax 스크립트문법 파일만든후, 제이쿼리로 자바스크립트 사용 -->
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" th:src="@{/ajax_test.js}"></script>

</body>
</html>
  • ajax_test.js (자바스크립트 파일 생성)

ajax 시작 문법

  • ajax을 사용하여 페이지이동(html)없이 화면움직일 수 있다.
    $.ajax({ url: '/ajax/ex2',type: 'post',data:{},success: function(result) {},error: function(){alert('실패');}});
function test1() {
	//test1()실행되면 ajax실행되는데 url이 컨트롤러로 간다
	//ajax start jquery
	$.ajax({
	    url: '/ajax/ex2', //요청경로
	    type: 'post',//postMapping방식으로 위 url컨트롤러 찾아간다
	    data:{}, //필요한 데이터
	    success: function(result) {//result에 return값 들어온다
	      //자바스크립트의 콘솔
	      
	      //ajax 데이터 뽑는 방법
	      console.log(result);
	      console.log(result.name);
	      console.log(result.age);
	      console.log(result.tell);
	    
	    
	    //list 일때
	    //데이터는 뽑는 방법 : result.name 안된다.
	    //그래서 반복문으로 
	    //[for문]
	   	/*for(let i = 0; i < result.length; i ++){
			console.log(result[i].name);		
			console.log(result[i].age);		
			console.log(result[i].tell);		
		}*/
		
		//[foreach문]
		for(const member of result){
			console.log(member.name);
			console.log(member.age);
			console.log(member.tell);
		}
		
	    },
	    error: function(){
	       alert('실패');
	    }
	});
	//ajax end
}

function test2() {
	//ajax start
	$.ajax({
	   url: '/ajax/ex3', //요청경로
	    type: 'post',
	    
	    // HongJava 라는 값을 name으로 데이터 던진다. 
	    data:{'name':'HongJava', 'age':20}, //필요한 데이터
	    success: function(result) {
	      alert('aaa');
	    },
	    error: function(){
	       alert('실패');
	    }
	});
	//ajax end
}

  • ajax에서 페이지이동하지 않고 데이터 뽑는 방법
  • list 데이터 뽑을 때

학생관리 페이지 구현_스프링부트

실습내용
localhost:8081/stu/list

  • 위 요청경로로 들어오면 학급목록과 학생목록정보가 화면에 나와야한다.
    <생성 파일 목록>
    • templates/stu_manage.html 파일 생성
    • kh.study.ajax.service.StuService
    • kh.study.ajax.service.StuServiceImpl
    • kh.study.ajax.controller.StuController
    • kh.study.ajax.vo.ClassVO
    • kh.study.ajax.vo.ScoreVO
    • kh.study.ajax.vo.StuVO
  • 학급목록은 셀렉트박스에 나타난다.(단,셀렉트박스의 기본값은 전체로 한다)
  • 셀렉트박스 밑에는 테이블로 학생 전체목록이 조회되면 된다.
  • 학생목록은 학번,이름,나이,학급명을 조회한다.
  • 화면은 양쪽분할로 테이블 1행 2열로 만들어 나타날수있도록 한다.
  • AjaxTest 프로젝트_ 필요한 파일


  • 먼저 DB에서 테이블 생성('Ajax_실습' 파일)
    : 테이블생성 및 데이터 삽입
--Ajax 실습 테이블
--학급정보 테이블
CREATE TABLE CLASS_INFO(
    CLASS_CODE NUMBER PRIMARY KEY
    , CLASS_NAME VARCHAR2(100) NOT NULL
);
--학생테이블
CREATE TABLE STUDENT_INFO(
    STU_NUM NUMBER PRIMARY KEY
    , STU_NAME VARCHAR2(100) NOT NULL
    , STU_AGE NUMBER
    , CLASS_CODE NUMBER REFERENCES CLASS_INFO(CLASS_CODE)
);
-- 학생 점수 정보 테이블
CREATE TABLE SCORE_INFO(
    SCORE_NUM NUMBER PRIMARY KEY
    , KOR_SCORE NUMBER DEFAULT 0
    , ENG_SCORE NUMBER DEFAULT 0
    , MATH_SCORE NUMBER DEFAULT 0
    , STU_NUM NUMBER REFERENCES STUDENT_INFO(STU_NUM)
);

INSERT INTO CLASS_INFO VALUES (1, '자바반');
INSERT INTO CLASS_INFO VALUES (2, '캐드반');
INSERT INTO CLASS_INFO VALUES (3, '디자인반');

INSERT INTO STUDENT_INFO VALUES (1, '김자바', 20, 1);
INSERT INTO STUDENT_INFO VALUES (2, '이자바', 30, 1);
INSERT INTO STUDENT_INFO VALUES (3, '박자바', 40, 1);
INSERT INTO STUDENT_INFO VALUES (4, '최자바', 50, 1);
INSERT INTO STUDENT_INFO VALUES (5, '정자바', 60, 1);

INSERT INTO STUDENT_INFO VALUES (6, '김길동', 15, 2);
INSERT INTO STUDENT_INFO VALUES (7, '이길동', 25, 2);
INSERT INTO STUDENT_INFO VALUES (8, '박길동', 35, 2);
INSERT INTO STUDENT_INFO VALUES (9, '최길동', 45, 2);
INSERT INTO STUDENT_INFO VALUES (10, '정길동', 55, 2);

INSERT INTO STUDENT_INFO VALUES (11, '김유신', 13, 3);
INSERT INTO STUDENT_INFO VALUES (12, '이유신', 23, 3);
INSERT INTO STUDENT_INFO VALUES (13, '박유신', 33, 3);
INSERT INTO STUDENT_INFO VALUES (14, '최유신', 43, 3);
INSERT INTO STUDENT_INFO VALUES (15, '정유신', 53, 3);

COMMIT;

  • student-mapper

    두 테이블을 이용해 조인하여 필요항목을 조회하도록 한다.
    그래서 학생정보테이블에는 학급명이 없어서 resultMap에 별도로 추가하는 대신 원래없던 학생정보StuVO에 학급명className 변수를 선언해야한다!

<?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="stuMapper">

	<resultMap type="kh.study.ajax.vo.ClassVO" id="classInfo">
		<id column="CLASS_CODE" 	property="classCode"/>
		<result column="CLASS_NAME" property="className"/>
	</resultMap>

	<resultMap type="kh.study.ajax.vo.StuVO" id="stuInfo">
		<id column="STU_NUM"   		property="stuNum"/>
		<result column="STU_NAME" 	property="stuName"/>
		<result column="STU_AGE" 	property="stuAge"/>
		<result column="CLASS_CODE" property="classCode"/>
		<result column="CLASS_NAME" property="className"/>
	</resultMap>
<!-- 학급목록조회 -->
<select id="getClassList" resultMap="classInfo">
	SELECT CLASS_CODE
		,CLASS_NAME
	FROM CLASS_INFO
	ORDER BY CLASS_CODE
</select>

<!-- 학생목록조회 (조인 ver.) -->
<select id="getStuList" resultMap="stuInfo">
	SELECT STU_NUM 
    , STU_NAME
    , STU_AGE
	, CLASS_NAME
	FROM CLASS_INFO C,STUDENT_INFO S
	WHERE C.CLASS_CODE = S.CLASS_CODE
	ORDER BY STU_NUM
</select>
</mapper>

만약 서브쿼리이용해서 학생목록조회한다면 아래 코드 사용

  • 학생목록조회 (서브쿼리 ver.)
<select id="">
	SELECT STU_NUM 
	    , STU_NAME
	    , STU_AGE
		,  (SELECT CLASS_NAME
			FROM CLASS_INFO
			WHERE CLASS_CODE = S.CLASS_CODE)
	FROM STUDENT_INFO S
	ORDER BY STU_NUM
</select>

(각 테이블 해당 VO파일 생성)

  • ClassVO
package kh.study.ajax.vo;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class ClassVO {
	private int classCode;
	private String className;
}
  • ScoreVO
package kh.study.ajax.vo;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class ScoreVO {
	private int scoreNum;
	private int korScore;
	private int engScore;
	private int mathScore;
	private int stuNum;
}
  • StuVO

    Mapper에서 resultMap 컬럼에 별도로 추가했으면 StuVO에도 추가해야한다.private String className;

package kh.study.ajax.vo;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class StuVO {
	private int stuNum;
	private String stuName;
	private int stuAge;
	private int classCode;
	//resultMap에 추가했으면 VO에도 추가
	private String className;

}

  • Service
package kh.study.ajax.service;

import java.util.List;

import kh.study.ajax.vo.ClassVO;
import kh.study.ajax.vo.StuVO;

public interface StuService {
	//학급목록 조회
	List<StuVO> getStuList();
	List<ClassVO> getClassList();

}
  • ServiceImpl
package kh.study.ajax.service;

import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import kh.study.ajax.vo.ClassVO;
import kh.study.ajax.vo.StuVO;

@Service("stuService")//컨트롤러연결
public class StuServiceImpl implements StuService {

	@Autowired//어노테이션으로 객체생성
	private SqlSessionTemplate sqlSession;

	//학급목록조회
	@Override
	public List<ClassVO> getClassList() {
		return sqlSession.selectList("stuMapper.getClassList");
	}
	
	//학생목록조회
	@Override
	public List<StuVO> getStuList() {
		return sqlSession.selectList("stuMapper.getStuList");
	}
}

  • StuController

    우선 ajax 사용안하고 html로 페이지이동!

package kh.study.ajax.controller;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import kh.study.ajax.service.StuService;
import kh.study.ajax.vo.ClassVO;
import kh.study.ajax.vo.StuVO;

@Controller
@RequestMapping("/stu")
public class StuController {
	//service 객체를 만들어줘야 안에 메소드사용가능!
	
	@Resource(name = "stuService")//@Service("/stuService") 인터페이스와 연결
	private StuService stuService;
	
	@RequestMapping("/list")
	public String selectStuList(Model model,StuVO stuVO, ClassVO classVO) {
		model.addAttribute("classList",stuService.getClassList());
		model.addAttribute("stuList",stuService.getStuList());

		return "stu_manage";//페이지이동
	}
}

타임리프_리스트데이터 뽑는 방법

  • 중요 point! 테이블 1열 2행을 구현하여 한화면에 양면분할로 만들어준다 -> css 중요
  • 컨트롤러에서 보낸 classList,stuList라는 이름으로 던져진 데이터를 받아서 classInfo,stuInfo라는 이름을 사용해 foreach문 타임리프를 이용해 각각의 리스트에서 하나씩 빼서 목록조회한다.
    th:each="classInfo : ${classList}"
  • 타임리프 text를 사용하면 실제로 데이터를 화면에 보이게 할 수 있다.th:text="${classInfo.className}"
  • 단, 코드에서처럼 학급명은 기본키인 학급코드로 value값으로 데이터를 받아야한다!(내부적)th:value="${classInfo.classCode}"></option>
  • stu_manage.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">

.layoutTable{
	width: 1000px;
	margin: 0 auto;
	border: 1px solid black;
	border-collapse: collapse;
	margin-top: 40px;
	text-align: center;
	
}
.layoutTable > tbody >tr, .layoutTable > tbody > tr >td{
	border: 1px solid black;
}
.layoutTable > tbody> tr{/* 자식 */
	height: 500px;
}
.layoutTable > tbody> tr > td{/* 자식 */
	vertical-align: top;
	padding: 20px;
}
.stuListTable{
	width: 400px;
	border: 1px solid gray;
	border-collapse: collapse;
	margin: 0 auto;
}
.stuListTable tr,.stuListTable td{/* 자손 */
	border: 1px solid gray;
}
</style>
</head>

<body>

<table class="layoutTable">
	<colgroup>
			<col width="50%">
			<col width="50%">
	</colgroup>
	<tr>
		<td>
			<div style="margin-bottom: 10px;" align="center">
				<select>
					<option>전체</option>
					<option th:each="classInfo : ${classList}" th:text="${classInfo.className}" th:value="${classInfo.classCode}"></option>
				</select>
			</div>
		
		<div>
			<table class="stuListTable">
				<thead>
					<tr>
						<td>학번</td>				
						<td>이름</td>				
						<td>나이</td>				
						<td>학급명</td>				
					</tr>
				</thead>
				<tbody>
					<th:block th:each="stuInfo : ${stuList}" >
						<tr>
							<td th:text="${stuInfo.stuNum}" ></td>				
							<td th:text="${stuInfo.stuName}" ></td>				
							<td th:text="${stuInfo.stuAge}" ></td>				
							<td th:text="${stuInfo.ClassName}" ></td>				
						</tr>
					</th:block>
				</tbody>
			</table>
		</div>
		</td>
		<td></td>
	</tr>

</table>
</body>
</html>
  • 결과
profile
Dev.Vinch

0개의 댓글