Spring/Blog-V1 23

스프링 37강. 블로그 세부페이지 수정

글쓰기 상세페이지에 삭제 버튼을 추가해주자. 수정 버튼은 수정 페이지 이동이니까 get요청 -> 하이퍼링크 삭제는 get 요청으로 할 수 없으니까 버튼으로 만들어준다. 현재 상태는 다른 아이디로 로그인해도 글 상세보기 페이지에서 수정과 삭제 버튼이 보이게 되어있다. 해당 게시글의 userId(FK)와 세션의 principal id를 비교해서 권한을 체크해준다. 동일하면 글 삭제 가능, 같지 않으면 글 삭제 불가능하게! delete 요청에는 body가 없기 때문에 게시글의 id로 한번 더 SELECT 해서 userid를 확인해야 한다. // DELETE 글 삭제 /post/{id} -> 글 목록으로 가기 - 인증 O @DeleteMapping("/s/post/{id}") public @ResponseBod..

Spring/Blog-V1 2022.03.18

스프링 36강. 스프링 json 파싱 @RequestBody

유저 수정 메서드에서만 스프링 기본 파싱 전략을 바꿔야 한다. 유저 수정은 자바스크립트 fetch 함수를 통해 json으로 데이터를 받을 것이기 때문에 스프링이 데이터 받을 때 json으로 파싱 할 수 있도록 기본 파싱 전략을 변경해줘야 한다. @RequestBody는 json으로 파싱 해주는 어노테이션이다. RequestBody와 ResponseBody를 붙이면 Raw 하게 버퍼로 읽고 쓰겠다는 말이다. 날 것 그대로! RequestBody를 안 붙이면 request.getParameter가 발동하여 x-www-form-urlencoded 타입만 파싱 하기 때문이다. 만약 (@RequestBody String user) 스트링 타입으로 받는다면 json이 스트링 타입으로 들어올 것이다. 이 타입을 Us..

Spring/Blog-V1 2022.03.18

스프링 35강. 스프링 구조 - OSIV, 영속화

스프링 Layer별 구조 1. 필터 역할 : 걸러주는 애 필터와 컨트롤러 사이에서 DB Connection 객체를 가져온다. == 세션 연결 (웹서버 아파치 톰캣 : request, session(id)으로 사용자 구분) ↓ OPEN SESSION / ↑ CLOSE SESSION : OSIV(Open Session In View) = TRUE 2. 컨트롤러 @Controller @RestController (String(text/html), 자바 오브젝트(application/json)) 역할 : 클라이언트의 요청을 받아 View나 Data를 응답 PutMapping( ) { 서비스.송금( ) } PutMapping( ) { 서비스.송금( ) } put매핑 요청은 fetch밖에 못한다! 3. 서비스 @S..

Spring/Blog-V1 2022.03.18

스프링 34강. id 중복체크

우리 블로그에는 한 가지 문제가 있다 기존에 존재하는 username으로 회원 가입하면 서버가 터져버린다. UNIQUE 제약조건에 위배된 것이다. 보통의 사이트에서 회원 가입할 때 아이디 중복확인 버튼이 만들어져 있었는데 그냥 키보드 입력 때마다 DB에서 이벤트 검사를 받을 수 있다. get요청이다. 이 아이디 DB에 있어? get 요청인데 Ajax 안 써도 되지 않을까? 안 쓰면 계속해서 전체 페이지가 새로고침 되기 때문에 get 요청인데도 Ajax를 사용한다. jQuery를 사용해주기 위해 헤더 레이아웃에 추가해주자. 일일이 머스태치 파일마다 추가하지 않아도 부분 템플릿으로 편하게 사용 가능하다. 우선 input 태그 dom을 찾아서 value 찾으려면 dom에 id를 부여해줘야겠다! 회원가입 키보드..

Spring/Blog-V1 2022.03.17

스프링 33강. 페이징

mariadb 페이징 SELECT * FROM post LIMIT 0,3; 주의할 점 첫 번째 숫자 0은 번지수, 두 번째 숫자 3은 한 페이지에 띄울 개수이다. 0, 3은 0번지부터 3개씩 페이징 하겠다는 말이다. 첫 번째 숫자만 바뀌면서 페이징 해주면 되겠다. 이렇게 네이티브 쿼리 만들어주면 되는데 jpa를 쓰면 알아서 페이징을 해준다. findAll 메서드에서 sort도 해주고 페이징도 해주는 메서드가 없다. 우선 정렬은 포기하고 실습해보자. findAll의 리턴타입이 Page인 것을 볼 수 있다. 페이지 타입은 어떻게 생긴 데이터를 건네주는지 테스트해보자. @ResponseBody를 걸어주면 RestController처럼 데이터를 리턴해준다. @GetMapping("test/post/list") ..

Spring/Blog-V1 2022.03.17

스프링 32강. 인덱스

USE greendb; CREATE TABLE boargreendbd ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(60), content LONGTEXT ); DESC board; 현재 쿼리 실행 단축키 Ctrl + Shift + F9 CREATE INDEX index_title ON board (title); SHOW INDEX FROM board; BTREE가 뭘까? 비트리를 알기 전에 다음 개념을 알고 가자. 다음과 같이 데이터가 저장되어 있을 때 지수를 찾기 위해 검색을 하면 기본적으로 풀 스캔한다. 3번째 데이터에서 지수를 발견했을 때 스캔을 멈출까? 멈추지 않는다. 지수는 유일한 값이 아니기 때문이다. 아래에 지수가 또 있을지도 모르니 끝까지 스캔..

Spring/Blog-V1 2022.03.15

스프링 31강. JPA Fetch 전략

JPA 쿼리 기본 전략을 바꾸기 위해서 JPA Fetch 전략을 알아야 한다. 변경 방법에는 Lazy(지연 로딩), Eager(즉시 로딩) 2가지가 있다. 우선 Lazy부터 사용해보자. user 오브젝트를 사용하기 전까지 user의 정보를 SELECT 해오지 않는다. 메인 페이지를 실행했을 때 SELECT 쿼리가 한 번만 일어난다. 메인 페이지에서는 user 오브젝트가 필요하지 않으니까! user 오브젝트가 필요한 글 상세보기 페이지로 가보자. 쿼리가 두 번 실행된다. post의 user 오브젝트가 null이었으니까 필요할 때 이제야 user를 SELECT 하는 것이다. 게으르게(Lazy)!! user 오브젝트가 null인걸 알아차리고 뒤늦게 SELECT 하는 타이밍은 컨트롤러가 뷰를 호출하기 전 mus..

Spring/Blog-V1 2022.03.10

스프링 30강. JPA 쿼리 기본 전략

터미널 창에 SQL 쿼리를 예쁘게 정렬해서 보여주는 설정이다. application.yml 파일에 추가해주자. spring: jpa: properties: hibernate.format_sql: true 터미널 창을 clear 하기 위해서는 Ctrl + Shift + A 커맨드 팔레트를 열어서 terminal:clear를 검색해줘야 한다. 과정이 귀찮으니까 오른쪽 설정 아이콘을 눌러 단축키를 설정해주자. 키 바인딩 빈칸을 더블클릭해 원하는 단축키를 설정해주면 된다. Ctrl + Shift + C로 설정해주었다. 이제 서버를 시작시키고 메인 페이지에 들어가 보면 post를 findAll( ) 하는데 이때 터미널 창에서 쿼리를 확인해보자. post만 SELECT 해오는 게 아니라 user까지 SELECT 하..

Spring/Blog-V1 2022.03.10

request 객체

request 객체가 가진 메서드에 대해 알아보자! https://swdevelopment.tistory.com/173 JSP / 톰캣의 내장객체와 해당 메서드 JSP페이지는 웹컨테이너겸 컴파일러인 톰캣에의해 서블릿 클래스로 변환되어 사용자의 요청을 수행한다. 서블릿 클래스가 인스턴스로 생성되고 사용자의 요청에 맞는 응답 페이지를 생성하기 swdevelopment.tistory.com request 객체 쿠키, URL/URI 요청 방식과 관련된 메서드 리턴 타입 메서드명 설명 Cookie[] getCookies( ) HTTP요청 메시지의 헤더에 포함된 쿠키를 javax.servlet.http.Cookie 배열로 리턴한다. String getServerName( ) 서버의 도메인명을 문자열로 리턴한다. i..

Spring/Blog-V1 2022.03.09

스프링 29강. 글 쓰기 페이지와 글 목록 페이지

// 메인 페이지 - 인증 X // GET 글 목록 페이지 /post/list/ @GetMapping({ "/", "post/list" }) // { "/", "post/list" }로 쓰면 두 가지 방법으로 들어올 수 있음 public String list(Model model, Post post) { List posts = new ArrayList(); // 1. postRepository의 findAll() 호출 posts = postRepository.findAll(); // 2. model에 담기 model.addAttribute("posts", posts); // 3. mustache 파일에 뿌리기 return "post/list"; } {{> /layout/header}} {{#posts}}..

Spring/Blog-V1 2022.03.09