스프링 / 2 + MyBatis
- promise : 비동기 결과를 갖고 있는 객체
promiseFuntion.then((data)=>{
console.log(data);
});
//이렇게 하면 데이터 꺼낼수 있음
//리젝트 : 약속깨짐. 오류?
const promiseFuntion = new Promise((resolve,reject)=>{
reject("약속이 깨졌어요");
return;
});
- 프로미스는 라이브러리를 직접 만들거 아니면 사실상 쓸일은 없다
< 오전 자스 + 돔 스터디 >
let likeBtn = document.querySelectorAll('.like');
let btnController = function(e){
let isLiked = e.target.classList.contains('active');
if(isLiked)
//비활성 상태
e.target.classList.remove('active');
else
//활성 상태
e.target.classList.add('active');
}
for(let i=0; i<likeBtn.length; i++){
likeBtn[i].onclick = btnController;
}
//눌릴때마다 함수가 실행된다
// for(let i=0; i<likeBtn.length; i++){
// likeBtn[i].onclick = function(e){
// //라이크버튼에서 인액티브가 잇으면 인액티브 없애고
// // if(likeBtn.classList.contains('inactive')){
// // //이렇게 하면 너무 직관적이지 않으니까
// //likeBtn.classList.add('inactive');
// // }else{
// // likeBtn.classList.remove('inactive');
// // }
// let isLiked = e.target.classList.contains('active');
// if(isLiked)
// //비활성 상태
// e.target.classList.remove('active');
// else
// //활성 상태
// e.target.classList.add('active');
// }
// }
- 타임리프의 루트는 템플릿이고 그 루트는 ~ 물결모양으로 표시한다
- 프래그먼트(fragment)
- :: 쓰면 가져오고싶은 id를 가져올수 있다
<div th:replace="~{inc/header::.nav-wrap}"></div>
//nav-wrap을 가져오겠다
//nav-wrqp은 클래스니까 앞에 쩜. 붙여주기
//라이브러리 사용방법
<html lang="en"
mlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
>
<!------------------------------------메인부분------------------>
<div layout:fragment="content"></div>
<html lang="en"
mlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{inc/layout}"
<!--인클루드에 있는 레이아웃이라는 애가 나를 꾸며줄거에요~-->
>
- header의 링크는 무조건 절대경로로! ex) /index
- 다른거랑 호환되는 문서들이라면 무조건 절대경로로 바꿔야 한다! 앞에 점점 .. 지워야함
- 타임리프는 html의 구조를 따르는게 맞다
- list는 컨텐츠를 꽂아넣는애 / layout은 공통된거 모아두는애
- 이렇게 하는 이유는 코드의 집중화 때문이다
- 자신이 갖고있는 경로는 상대경로로 해야됨
< 사용자 입출력 >
package kr.co.rland.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("menu")
public class MenuController {
@GetMapping("list")//->get/post 요청을 겸비
public String list(String c) {
System.out.printf("c:%s",c);
return "menu/list";
}
//http://localhost:8080/?menu/list?c=2 이렇게 도메인을 치면됨
@GetMapping("detail")
public String detail() {
return "menu/detail";
}
}
@GetMapping("list")//->get/post 요청을 겸비
public String list(String c, int p) {
System.out.printf("c:%s, p:%d\n",c,p+1);
return "menu/list";
}
- http://localhost:8080/menu/list?c=1&p=5 이렇게 하면 콘솔에 저렇게 잘 찍힘!
(정수형 덧셈 가능)
public String list(String c, @RequestParam("p") int page)
//@RequestParam : page라는 변수를 브라우저에서는 p라는 글자로 인식하게 하는것
//도메인에서 page말고 http://localhost:8080/menu/list?p=1 라고 검색하면 된다
@RequestParam(name = "c",defaultValue = "1") int categoryId,
//defaultValue : 기본값을 1로 설정한다
@RequestParam(name = "p",defaultValue = "1") int page) {
//null값이 필요할때 쓰는애 : required
@RequestParam(name = "c", required = false) int categoryId,
- null이라는것도 값종류중 하나이기때문에 이런게 존재하는것. (null값이 필요할때 쓰도록 하자 !)
- @RestController
라는 어노테이션을 붙이면 사용자에게 화면이 아니라,데이터 자체를 반환하게 된다.
- @ResponseBody
내가 리턴하고 있는 내용 그 자체가 사용자에게 곧바로 가면 좋겠다 할때는 이런 어노테이션을 씀 (위에 레스트 컨트롤러랑 비슷함)
- 객체를 생성해서 나에게 던져주는 = 스프링의 DI 기능
- 컨트롤러는 ui에 해당하는 껍데기일 뿐이다
- 자료형은 특정한 클래스를 언급하면서 걔가필요해!! 라고 하면 코드의 결합력이 너무 강해져서 좋지않다 (느슨한 결합을 해야함)
//구현체는 중요하지않고 그냥 메뉴 갖고잇는 애들만~
//이게 느슨한 결합(인터페이스)
public interface MenuService {
}
- 껍데기는 계속 바뀌고 업무는 웬만하면 그대로 가기 때문에 느슨한 결합을 지향해야 한다