겟요청의 쿼리값 받기


쿠키활용

 

다음에도 그대로 유지되서 문서를 만들기원한다면

서버에 전달하기위한 방법ㅇ ㅣ필요하다

현재값을 유지하려면 지금값을 꽂아줘야한다

 

1. 쿼리스링조작 

2. 상태가 유지될수있도록, jsp안에서 요청할때마다 계속꽂혀야하는값이있다.

 쿠키를 통해 쓰지않아도 올떄마다 가져오게한느방법

 

쿠키 : 클라이언트가 올떄마다 가지고오는 , 브라우저가 알아서가져옴, 페이지요청시 그값이온다. 

서버 4대저장소 페이지콘텍스트,리퀘스트,세션,어플리케이션

 

쿠키사용방법

클라이언트에게 다음부터가지고다녀라고 요청하는것

응답으로보내줌

 

임시적인 상태값 유지

쿠키 : 브라우저가 닫힐때까지 (브라우저가 쿠키를 기억함)

        쿠키로 사람을 식별하면 위조가능(보안적으로는위험)

         쇼핑몰에서 장바구니,   

        비회원에서 장바구니이용하면 브라우저에게 요청     

        사용자가 협조적이어야 ...

 

 

세션 : 서버는 연락이오고 연락이끊기면 브라우저와 상관없이, 마지막요청이 있고난 후 세션타임아웃이 제로가되면 

자원을해제한다.

       세션이 비대해지면 자원이 비대해지면 장소부족으로 부담이생긴다

       서버자원을많이쓰면 서버메모리많이씀

       회원이 장바구니이용

새로고침하면 콘솔출력

파람이라고하면 4대저장소가아닌 파라미ㅌ어ㅔ서찾는다

 

쿠키설정:

1생명주기 

2가시영역(어느범위내에서?)

 

브라우저는 프로세스가 닫혀야한다

브라우저창의 여러탭중에 탭을끄면 쓰레드하나끄는것뿐

위 크롬을 다닫아야 쿠키가 사라진다

브라우저 닫았다가 다시실행하면 query cookie : null

 

브라우저닫아도 담게하려면 ?

브라우저를 끄고 다시 키켜도 남아있다면 생명이 유지되는것


쿠키 가시영역

자식디렉토리에서는 같이쓸수있다.

상위(전체)에서쓰러면 범위를 넓혀야한다

쿠키는 무조건 문자

쿼리스트링에쓸 수있ㄴ느값만가능

 

 


쿠키가져오기

 


restAPI

id를 경로로 씀

나머지쿼리값은 그전처럼사용

https://deeplify.dev/back-end/spring/port-is-already-in-use

 

[스프링/Spring] Port 8080 is already in use 에러 해결 방법

스프링에서 가끔 발생하는 8080 포트는 이미 사용중이라는 에러에 대해서 알아보고 해결하는 방법까지 알아보도록 하겠습니다.

deeplify.dev

 

작업관리자 - 세부정보 - 자바파일 작업끝내기

netstat -ano

taskkill /f /pid 12345

서비스란 

내가필요한 서비스를 만들어야 돈이 된다.

 

 

업로드한 파일 이용하는 방법

빈공백이없는 엘리먼트만대상으로할때 firstElementChild

텍스트노드빼고!

파일업로드의 진척도표시

눈에보기쉽게 바로 진척도를 나타낸다면 ?


파일경로를 출력해보자


서버에서 인코딩설정


편집기

윗칸은 작성하고있는내용을 미리보여주는칸

아랫칸이 실질적으로 전송되는 내용 

아랫칸이 숨김으로되면 작성자는 작성한내용자체가 전송되는것처럼보인다.

서버에올라간것 미리보기

 


첨부파일의 파일선택은 서버에 안올라갔지만 이미지가 나오게한다.

파일이 선택되면 ->이미지추가

이미지첨부파일을 선택하면 미리보기가 나타난다.

 

콘텐트에 이미지가 보인다면 저장할필요없다. 콘텐트에 경로를 입력할것이기때문에

컬럼이들어간건 별도의 첨부파일만 씀

파일즈 : 파일이 여러개 올라갈수있다

파일의 목록을 구분자로넣어서 파일하나를 다룬다

시퀄보다는 자바라던지 제어문으롲 ㅣ워야한다 

장점 :삽입할때편하다


여러개파일일경우는 ?

여러개파일을 업로드 하는경우는 ?

하나의값만받음
배열로받음


파일을 두개이상 보낸다면 ?

같은이름으로 보내도된다 name = f


하나의 파일즈컬럼에 두개의파일을 담을것

한 열에 파일두개를 등록할것

쉼표를 이용해서 두개의 파일을 디비에 등록

총 12글자(길이)에서 11글자만넣어야하므로 -1해준것


파일을 전달하지않으면 에러발생 널이전달

 


내가 한 게시글에서만된다

forTokens는 문자열을 쪼갠다. 쪼갠문자열을 반복한다

하이퍼링크가 두번반복될것
첨부파일이름을 클릭하면 다운로드된다.

데이터베이스는같이쓰지만 웹서버는 각각다르므로 다른사람의 첨부파일을 클릭하면 404에러가난다

자기웹서버의 디렉토리에있으므로..


라스트가 아닐경우에만 포함


인덱스로적용

3개가 조회된다 (0~2)


파일명에 마우스오버하면 절대위치가보인다. 어드민인지 확인할것


아티클쓰는 중간에 저장하려면 

페이지내에서 화면이뜬다

드래그드랍으로 업로드

-톰캣구동시 오류발생

[Tomcat 에러]Several ports (8005, 8080, 8009) required by Tomcat v9.0 Server at localhost are already in use. The server may already be running in another process, or a system process may be using the port. 

 

-기본포트 (8080,800,8005)가 이미 사용중이라 발생

-cmd창에서 pid 삭제하기

 


netstat -p tcp -ano :연결된 pid 확인

-로컬주소 8080, 8009, 8005찾기

-해당 포트 pid 번호확인 : 9608

-9608삭제 taskkill /f/pid 9608

-pid 목록 재확인 

 

DIRTY WORKTREE

merge된 worktree가 바르지않다면 오류가 발생.

 

수정된내용을 STAGED CHAGNES로 옮기기 -> COMMIT

프로젝트명 옆 화살표 - commit -push -non-fast forward발생

다시  team - pull (fetch+merge)

fetch(bring data) -merge(into workspace)

 

아예 브랜치를 새로 만들어야하는 경우가 발생할 수있다.


rejected non fast forward

기존업데이트에다가 머지하면 오류

충돌발생

commit-push(오류) non fast (또다른 최신버전존재)-> 화살표안내 (머지필요) pull

최신상태에서 commit-push

1. Dynamic Web Project 생성

2. Context root : ROOT를 자동으로 Document Root로 되므로 "/"로 바꿔준다.

 

3. 테스트할 html파일 생성

 

4. 새로운 서버설정

 

5. html실행 및 확인

 

6. 해당 프로젝트선택 -> 마우스오른쪽 클릭->team -> share project

   create a new git repository

 

7.  Project Explorer에서 해당 프로젝트에 물음표가 생긴다.

 

8. 해당프로젝트선택 ->마우스오른쪽 -> team -> add to index

폴더는 *로 html파일은 +로 바뀐다.

 

9. team->commit ->메세지작성 -> commit 

.

 

10. staged changes가 커밋 후 사라진다.

project explorer에서 폴더 및 파일의 표시도 노란색 박스모양으로 바뀐다.

 

 

11. 6. 깃허브에 새로운 레파지토리생성 및 레파지토리 주소복사

 

12. git staging 에서 push를 누르면 git repository 창에 복사란 url에 자동으로 들어가있다. 

 

13. 해당 깃 레파지토리를 새로고침하면 확인가능

'2021 Newlecture > Git&GitHub' 카테고리의 다른 글

Pull Request  (0) 2021.07.21

.

정규화 :

정규화1,2,3을 외우는게아니라 느낌으로 속성만보고 구별,의심이 가야함
중복제거

1정규화란 ?
하나의 컬럼값만 넣어야한다. (원자성)
특정컬럼이 두개이상 가질 가능성이있다면 중복유발
속성중에 2개이상 들어갈 수있는것 ? 

ex : 댓글내용,댓글등록일자
공지사항입력할때 제목은 하나만 넣는가 ?
작성자 이름은 하나만 넣는가 ?
댓글이 여러개 달릴 수있는가 ?

컬럼은 방이다. 
댓글컬럼이 늘어난다면 ? 100개의 댓글컬럼을 만들겠다 -> X  
컬럼은 유동적이지않다. max값을 생각해야함
연회장처럼 하객에 따라 써야함
데이터는 수직으로늘려야한다.
ex 댓글 : 공지사항과 같은 테이블에 담아야한다면 공지사항의 아이디,제목,작성내용이 중복발생한다.

공지사항 - 댓글

1:N형태

위반되는컬럼떄문에 다른컬럼의 중복이 발생한다

컬럼이 2개이상 가질가능성이있다면 업무자에게 물어봐야한다.

ex 업무자가 원테이블식당이라고하면 테이블번호는 1정규화위반이 아니다.


3정규화

아이디가 달라져도 형태,지역명은 이전데이터가 쓰인다. ( 아까 넣은 데이터가 또 들어가는것)

올드한데이터중복

 

3정규화위반 : 작성자이름,작성자연락처,등급

앞의 레코드를 다음에넣을때 또 넣을 수있는 가능성찾기

첨부파일용도가 정해진 키워드라면 3정규화위반가능

2정규화 :

부분 함수 종속성을 없앤다

작성자에 대한 정보가 필요하면 참조.

 

 

설계란 ?
 내가 말하고싶은것을 그린것(디자인)

IT기술에만 국한해서 생각하지말것

 

 

개념설계 :

ER 다이어그램

 

논리설계 :

관계형 ,테이블형태 (공통분모형태)

 

물리설계: 

물리적으로 DBMS선택해야함

실질적으로 물리적 공간에 저장하기위해 각각에 대해 정의



키의 종류
1. 주키(primary key) : 식별키,일련번호, 아이디
2. 후보키 : 기본키 처럼 식별용으로 쓸 수 있는 키
3. 대체키 : 후보키에서 기본키 이외의 키

4. 슈퍼키 : 2개 이상의 컬럼이 모여 기본키로 사용

5. 외래키 : 두 테이블을 서로 연결하는 데 사용되는 키

 

키의 종류

- 실선(Identifying): 식별관계

-> 부모 테이블의 기본키를 자식 테이블이 가지고 있으며 이를 기본키로 사용하는 경우

-> 부모가 있어야 자식이 생기는 경우

ex) Issue 테이블과 IssueComment 테이블이 있을 경우, IssueComment는 Issue가 존재해야지만 있을 수 있음

 

- 점선(Non-Identifying): 비식별관계

-> 부모 테이블의 기본키를 자식테이블이 가지고 있지만 이를 기본키로 사용하지 않을 때 

-> 부모가 없어도 자식이 생기는 경우

ex) User 테이블과 Process가 있을 경우, User가 담당 프로세스가 있다고 하더라도, Process는 User없이도 존재할 수 있음

 

정규화 : 

normalization 표준화,정상화

무결성 -> 데이터 중복제거
중복이 발생하는 패턴에서 중복제거

1정규화 : 모든 도메인이 원자값으로만 이루어져야만 한다. 
    도메인 : (유효한) 값의 범위

              ex이메일 : 123 (X)
    원자값 : 하나의 값만 이루어져야만 한다. 

              ex기업고객의 아이디가 하나만

속성을 봤을때 1개가 만들어갈지 n개가 들어갈지 또는 n개까지인지 찾아보기.

1개만 받는다면 원자값 , 여러개면 원자값이 아니다.

(전화번호 여러개인지 ?, 설립일이 여러개인지 ? )

 

1정규화 위반되는것 찾기 (테이블로뽑을지, 구분자로 구분할지선택 )
*노하우 - 이미지
*일기- 키워드
*공지 - 파일

관계표현


3정규화

아까들어갔던 내용이 계속 들어가는것(ex 여고괴담처럼 자꾸 졸업앨범에나타남)

 

책임자이름,매니저이름,매니저연락처,매니저이메일  ->중복제거 (자식을만들어야함)

올드데이터 : 미리있어야하는것이므로 별도 테이블 생성 ->외래키가 늘어나게된다. 

3정규화

 

일정이 새로생겨도 분류는 기존것이 그대로 사용된다.

 

설계할때는 한글로쓰기 (영어를 쓰면 의미가 왜곡될 수있다.)

회원 - 구매 - 상품 (n;n )

한 회원이 여러개의 상품을구매할 수있다.

한 상품이 여러 회원에 의해 구매된다.

식별자 : 언더라인

 

속성,관계고치기

 

사용자행위로서의 관계

사용자구성으로의 관계

 

행위자, 행위, 키 구분

-반려동물을 선택한 후에 일정이뜬다면 구성

-댓글은 행위. 기존에 있던것에 대한 행위. 노하우,일기에 대한 댓글

-노하우가 있어야만 댓글이 달릴 수있다. (키가 될 수 없다)

-좋아요도 행위, 대상이 될 수없다.

-회원이 여러 노하우글에 댓글을 달 수있다.

-노하우에 여러회원들이 댓글을 달 수있다.

좋아요는 행위다.
회원 - 좋아요 -리뷰 (n : n)

회원 - 댓글 - 노하우 

회원 -친구(신청) : 바로신청되는모습

논리 : 테이블형태 (공통분모형태)
물리설계: 물리적으로 DBMS선택해야함
탭으로왔다갔다

for in , for of 차이

동일 html에 적용했을때 비교 

    <h1>
        <span>R</span>
        <span>A</span>
        <span>I</span>
        <span>N</span>
        <span>B</span>
        <span>O</span>
        <span>W</span>
    </h1>

 

for...in (객체순환)

index return


        const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']; 
        let span = document.querySelectorAll('span');
        for(let i in colors){
            span[i].style.color = colors[i];
            console.log(i);// in : 0,1,2,3,4,5,6 인덱스번호
         
        }

for in 결과

 

for...of (배열 값 순환)

해당 value return


        const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']; 
        let span = document.querySelectorAll('span');
        for(let i of colors){
            span[i].style.color = colors[i];
            console.log(i);//of : red, orange, yellow, green, inigo // span[red] 이므로 오류 
        }

for of 결과

 

데이터베이스 모델링

 

테이블정하기

속성쓰지말고

테이블명으로 사용할수있는것들

 

메뉴를 뽑는게아니라 역할을 뽑아야한다

 

쇼핑몰에서의 역할자

 

회원이 등록하는 대상

개인정보,

장바구니,

 

 

비회원이 등록하는 대상[데이터베이스 모델링]

DBMS 종류
-RDBMS, OODBMS, ...

RDBMS : Relational DBMS
관계형 DB 

무결성 : -> 데이터 중복을 제거하는 방식으로 -> 파일(뷰)-> 쪼갬(집중화) -> 테이블

사용할 때는 :
테이블 -> 합쳐서 (뷰)-> 파일

테이블을 합칠 때 기준?
객체지향DB, RDBMS:관계

관계가 무엇인가요?
: 행위를 말한다.


주어(테이블) 동사(행위:관계) 목적어(테이블)

[회원:주어]이 [게시글:대상]을 등록[행위:관계]하다.


[제일 먼저 해야 할 가이드 1]
주어를 찾는 것.==주체를 찾는 것==행위자를 찾는 것==역할자를 찾는 것

사람수 != 역할자수

---------- ICODA를 보면서 이 사이트에서의 역할자를 찾으시오 ---------
회원
비회원
관리자
판매자

------ 역할자를 찾았으면 등록이라는 행위를 하게 되는 대상을 찾으시오.-----
-회원(이) [  ]를 등록하다.

관심상품 X : 회원이 상품을 등록하진않는다.

행위는 두개넣지말기

 

-관리자(이) [  ]를 등록하다. 

판매자관리

-판매자(이/가) [  ]를 등록하다. 

 

 

------ 위의 문제에 대한 리뷰 -------------
회원이 등록
- 회원정보 (주소, 이름, 전화번호,,)
- 장바구니 (X) ==> 등록하다에 어울리는 대상은 아님  ~에 "담다"를 말하는 행위에 더 어울림
- 관심 상품  ==> 합성어는 단위를 쪼개서 처리해야 함. 행위를 명사에 붙여서 표현하면 모든 것이 대상이 될 수 있음.
- 상품 평
-           상품정보 ==> 정보라는 어휘는 생략하는 것이 바람직함.
- 상품 문의 (질문) 

<가이드>
1. 합성어는 분리하고 분리한 어휘에서 행위는 제거하시오.
2. 정보라는 단어는 제거하시오.
3. 그 후에 남은 어휘가 등록이라는 대상에 어울리는지 확인하시오.
4. 속성명은 그것의 구조화된 데이터로 변경하시오.

-------------------------------------------------------------------
회원이 [글]을 등록하다.
관리자가 [이벤트/공지사항/배너광고] 등록하다.
판매자는 [상품]을 등록하다.

 

데이터베이스 설계

개념설계

논리설계

물리설계

 

개념설계(Concept..)

Entity-Relation 

 

키를 뽑는다.

관계를 찾는다. (등록, 수정, 다른동사 찾기)

 

등록이 데이터가쌓이거나, 삭제내역이쌓이면,조회내역이쌓이면(레코드가 쌓이면) ->데이터베이스에 관계표시

임시데이터는 데이터베이스를 사용하지않는다.

 

 

[ 회원 ]이 [ 배너광고 ]을 [ 조회 ]하다



=== < 리뷰 > =========================================================

행위를 뽑아서 보면… 다음과 같은 것들을 체크해야 한다.

 

  1. 업무적으로 다루는 내용인가.
  2. 행위가 데이터를 누적하는가? 추가로 누적되는 데이터가 없다면  관계로 보지 않는다..

예) 수정/삭제 -> 위키를 아시나요? 위키에서는 글을 수정하면 누가?언제?무엇?..을 저장해요. 그러면 이렇게 수정된 내역이 추가된다면 그것은 관계로 간주한다.

관계는 데이터베이스에 등록되는 것만을 대상으로 한다.

  1. 위의 내용을 만족하기는 하나 데이터를 별도의 파일이나 저장소를 이용하는 경우는 데이터베이스의 관계에서 제외된다.

 

데이터베이스를 사용하지 않고 다른 저장소를 선택하는 기준이 있느냐?

  • 임시 데이터
  • 수정/삭제/등록 과 같은 조작을 수반하지 않고 읽기 전용 데이터를 기록하는 경우



[판매자]가 [상품]을 [등록/수정/삭제/조회]하다.

[회원]이 [상품]을 [구매//조회/평가]하다.

[관리자]가 [상품]을 [등록/수정/삭제/조회]하다

 

값 :

8진수 / 2진수

 

변수:

var -> let

지역변수 / 지역화

 

const :

상수형변수

 

문자열 : 템플릿 문자열

어금부호로 감싸는 문자열

값을 포맷하거나 내려쓰기 등이 자유롭다

Escapte 문자를 포함하고 싶다면 ?

String.raw`...\n\n`

 

JSON이 향상되었다.

변수에 담겨진 값을 이용해 Object를 만들때

 

뽀개기 : 객체가 가지고있는 속성들을 지역변수화해서 값을 옮겨담는 작업 

	let kor = 30;
	let eng = 40;
	let math = 50;
	
	let exam = {
		kor :kor,
		eng :eng,
		math:math,
		total:	function(){
		console.log("total");
		}
	};
	console.log(exam.total());
	
	exam = {
			kor,
			eng,
			math,
			total(){
		console.log("new total");
	}};
	
	console.log(exam);
	console.log(exam.total());
	
	exam = {
			kor,eng,math,total(){console.log("prac");
			}
	}
	console.log(exam.total());

 

객체의 키를 변수로 사용

	let attr = "kor";
	let exam = {
		[attr] : 1,
		eng : 2
	};
	console.log(exam.kor); // 1출력
    
    	let attr = "kor";
	let exam = {
		[attr+"1"] : 1,
		eng : 2
	};
	console.log(exam.kor1);

객체를 뽀개지않고  사용하는 방식은 가독성이나 실행 성능을 낮춘다.

 

function printExam(exam){
	//뽀개기 Destructuring
	/*let kor = exam.kor;
	let eng = exam.eng;
	let math = exam.math;*/
	//let{kor, eng, math} = exam;
	let{kor,eng,math,avg=100} = exam;
	console.log(avg);//100
	
	let total = kor + eng+math;
	console.log(`kor:${kor}, eng:${eng}, math:${math}`); //ex2.js:485 kor:10, eng:20, math:30
	console.log(`total is ${total}`)//ex2.js:486 total is 60
}

let exam = {
	kor:10,
	eng:20,
	math:30
}

printExam(exam);

 

별칭사용

let{kor:k, eng, math, avg=100} = exam;
console.log(k) // 10

대괄호 변수선언

let [x,y] = [2,3];
console.log(x);//2
console.log(y);//3

[x,y] = [3,4];
console.log(x);//3
console.log(y);//4

[x,y] = [y,x];
console.log(x);//4
console.log(y);//3

[a,b] = [b,a] : 임시변수없이 교체가능

 

선언없는 할당

코드블럭( )으로 감싸기.

let a;
let b;
[a,b] = [10,20];
console.log(`a:${a},b:${b}`); //a:10,b:20

let kor;
let eng;
({kor,eng} = {kor:80, eng:90});
console.log(`a:${kor},b:${eng}`);//a:80,b:90

 

let notices = {
	title:"공지사항목록",
	list:[
		{title:"굿~", content:"좋아요~"},
		{title:"호호~", content:"웃음소리~"}
	]
};

//let {list:[{title}]} = notices;//굿
let {list:[,{title}]} = notices;//호호

console.log(title);

 

조인은 평상시쓰는것이므로 연습해야한다

 

VIEW

뷰: 멀리볼수도, 작게볼수있는 보고싶은대로 테이블단위

실질저장모델은 아니지만 , 그모양자체를 하나의 다른이름으로 사용가능,코드를 단순화시킴

수정,삭제,업데이트불가, 조회(읽기)전용의 테이블형태이다. 1.복잡한쿼리간단하게, 2.사용자가들이 볼수없게 가림

CREATE VIEW NOTICE_VIEW21 
AS 
SELECT N.ID, N.TITLE, N.WRITER_ID, N.REGDATE, N.HIT, N.FILES, M.NAME WRITER_NAME, COUNT(C.ID) CMT_COUNT
FROM NOTICE N 
    LEFT JOIN MEMBER M ON N.WRITER_ID = M.NICNAME 
    LEFT JOIN "COMMENT" C ON N.ID = C.NOTICE_ID 
    GROUP BY ROWNUM, N.ID, N.TITLE, N.WRITER_ID, N.REGDATE, N.HIT, N.FILES, M.NAME;

SELECT * FROM NOTICE_VIEW21 
WHERE ROWNUM BETWEEN 1 AND 10 
ORDER BY REGDATE DESC;

 

SELF JOIN

자기가 자기자신을 조인

데이터가 서로 포함관게를 가지는 경우 : 담당,구성,연락

EX 게시글의 댓글이 댓글이참조하는경우

참조키가 다른테이블이아니라 자기것

참조키는

SELECT M.*, B.NAME BOSS_NAME 
FROM MEMBER M
    LEFT JOIN MEMBER B ON B.NICNAME = M.BOSS_NICNAME;

 

SELECT M.*, B.NAME BOSS_NAME, B2.NAME B2_NAME 
FROM MEMBER M
    LEFT JOIN MEMBER B ON B.NICNAME = M.BOSS_NICNAME 
    LEFT JOIN MEMBER B2 ON B2.NICNAME = B.BOSS_NICNAME;

B2.NICNAME (부모)= B.BOSS_NICNAME;(자식)

자식이 부모를 참조하는 형식 

 

부모가 자식을 참조할수없음 

 

CROSS JOIN

실무에서 쓰일일이 적음

 

조인대신 서브쿼리사용

그동안 조인해서 그룹바이 집계

부모의 컬럼을 추가할땐 조인해서 컬럼추가했었다.

컬럼을 가져와야할 경우 컬럼추가시 조인하지않고도 가능하다

 

서브쿼리로 간단히 가능

 

INNER JOIN (교집합)

문장암기할것

-결과물 총 28개

-멤버 : 25개

-노티스 : 45개

노티스가 멤버의 NICNAME을 참조하고있다.

SELECT * 
FROM 
    MEMBER INNER JOIN NOTICE 
    ON MEMBER.NICNAME = NOTICE.WRITER_ID;

 

OUTER JOIN (합집합)

OUTER도 포함시키는 조인

OUTER(관련없는 것)

부모테이블의 아우터,

자식테이블의 아우터 각각 존재가능

 A의 모든 열 더하기 B에 있는 공통부분

 

LEFT OUTER JOIN 

멤버의 모든열 + 노티스에 있는 공통부분

SELECT * 
FROM 
    MEMBER LEFT OUTER JOIN NOTICE 
    ON MEMBER.NICNAME = NOTICE.WRITER_ID;

6개 만들어진다

RIGHT OUTER JOIN 

NOTICE의 모든열 + 멤버에있는 공통부분

SELECT * 
FROM 
    MEMBER RIGHT OUTER JOIN NOTICE 
    ON MEMBER.NICNAME = NOTICE.WRITER_ID;

노티스의 이너3개+아우터2개 = 5개

FULL OUTER JOIN 

A와 B의 합집합

8개

JOIN은 중요하므로 익숙해져야한다.

필드이름의 충돌문제

두개의 테이블을 합칠경우 컬럼이름이 중복될 수있다.

별칭을 붙여서 사용할수있다.

SELECT N.ID, NAME 
FROM 
    MEMBER M INNER JOIN NOTICE N 
    ON M.NICNAME = N.WRITER_ID;

 

INNER JOIN의 특징 : 

모든회원이 조회되지않고, 글쓴회원만 조회된다.

SELECT M.NICNAME, M.NAME, COUNT(N.ID)
FROM 
    MEMBER M INNER JOIN NOTICE N ON M.NICNAME = N.WRITER_ID
    GROUP BY M.ID, M.NICNAME ,M.NAME;

from에있는걸 먼저 집계한후 진행

 

3개 테이블 조인하기

SELECT N.ID, N.TITLE, N.WRITER_ID, M.NAME WRITER_NAME ,COUNT(C.ID) CMT_COUNT
FROM 
    NOTICE N 
    LEFT JOIN MEMBER M ON N.WRITER_ID = M.NICNAME 
    LEFT JOIN "COMMENT" C ON N.ID = C.NOTICE_ID
    GROUP BY N.ID, N.TITLE,N.WRITER_ID, M.NAME;

자식과합치면 부모가 2,3개씩 늘어난다.(중복발생)

집계해야만 자식을 내 레코드에 껴넣을수있다.

 

페이징시 WHERE절 필요

 

 

stanleykou.tistory.com/entry/SQL-INNER-%EC%A1%B0%EC%9D%B8%EA%B3%BC-OUTER%EC%A1%B0%EC%9D%B8%EC%9D%B4-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94

( Ajax ) ``억음부호 ${ } / insertAdjacentHTML / JSON.parse

로딩화면만들기

 

검정화면 나타내기

 

검은색화면이 생기고 사라진다.

이미지를 가운데위치시키기위해 flex, center적용

dom을 쓰는것보단 ``억음부호안에다가 넣어서 쓰는게좋다.

JSON 라이브러리

원래는 json형식으로 format에 담아서 문자열을 누적해야했다.

그동안 println(list)넣은것은 운좋게 작동했던것. 빈공백이나 문자열에러가 발생해왔다.

{notice },{notice },{ }가 들어가야한다.

쉽게만들어주는 라이브러리가있다. list객체를 json규격의 문자열로 바꿔준다.

gson 다운로드 -> WEB-INF>lib에 넣어준다.

수정페이지 흐름

1.edit.jsp에서 form태그의 action을 "edit"으로 method는 "post"로 지정

 

2. 동일 url을 갖고있는 EditController.java와 맵핑

사용자가 입력한 id,title,content가 notice객체 담겨 update함수의 파라미터로 전달된다.

사용자에게는 sendRedirect에 연결된 detail페이지가 보여진다.

3. NoticeService.클래스에 update()메소드를 생성한다.

가져온 notice객체를 파라미터로 받는다.

sql문에는 수정될 항목에 = ? 를 넣는다.

?를 넣을 수있도록 PreparedStatement객체를 만들고

notice.getTitle()로 제목을 불러온뒤 setString에 넣는다.

결과값은 excuteUpdate()를 이용해 담는다.

수정한  내용 저장하기

NoticeServiece.java에서  update()에{ } sql,url, forname, connection  복사붙여넣기

CreateStatement 대신 PreparedStatement사용

Update/Delete/Insert는 executeUpdate()사용

 

수정->저장을 누르면 상세내역에서 저장된 내용이 보인다.

등록페이지만들기

<form action="URL">

폼 데이터(form data)를 서버로 보낼 때 해당 데이터가 도착할 URL을 명시

 

edit.jsp복사해서 reg.jsp만들기

list.jsp에서 글쓰기버튼만들기

reg.jsp  / list.jsp

 

사용자가 저장을 누르면 post된다.

등록처리만 하는 컨트롤러필요

redirect 가 다시 목록페이지로간다

콘솔창에 에러가없었는지확인할것

SQL오류가 발생

현재로그인한 정보를 넣어야하는데,

일단 자기계정넣기

 

삭제하기기능

doget요청할것

Select : executeQuery(sql)

Update , Insert, Delete : prepareStatement(sql)


조인(join) : 테이블을 하나로 합치는것

참조:관계형, 참조해서 합쳐서쓴다

 

멤버가있어야 글을 쓸수있다.

멤버 데이터 -> 등록하는 행위

 

참조되는녀석 : 부모

참조하는 녀석 :자식

FROM에는 테이블외에 격차형이 올수있다.

 

중복이 발생

url만 다를뿐 

중복코드를 줄이고, 페이지번호를 누르면 목록을 바로 출력하자

하단번호를 누르면 목록이 보인다.

 

window.addEventListener("load", function() {
	var section = document.querySelector("#ex10");
	var tbody = section.querySelector("tbody");
	var requestButton = section.querySelector(".btn-request");
	var pager = section.querySelector(".pager");
	
	function bind(url){//데이터를 화면에 연결
		var request = new XMLHttpRequest();
		request.onload = function() {
			var list = JSON.parse(request.responseText);

			var trEmpty = tbody.querySelector(".empty");
			if (list.length > 0 && trEmpty != null)
				trEmpty.remove();

			for (var i = 0; i < list.length; i++) {
				var tr = `<tr>
							<td>${list[i].id}</td>
							<td>${list[i].title}</td>			
						</tr>`;
				tbody.insertAdjacentHTML("beforeend", tr);//
			}
		};/*request*/
		
		request.open("GET", url, true);//false 동기
		request.send(null);
	}

	pager.onclick = function(e) {
		e.preventDefault();

		if (e.target.tagName != "A")
			return;

		var page = e.target.innerText;//사용자가누른 페이지

		bind(`../api/notice/list?p=${page}`);	
	};

//request버튼누르면 목록나열
	requestButton.onclick = function(e) {
		bind("http://localhost:8080/api/notice/list");

	};/*requestButton*/
});

 

Q. 기본 1페이지가 로드되자마자 보이도록하려면?

bind()메소드를 밖으로 빼낸다.

로드되자마자 보이게됨

Q. 2페이지를 누르면 2페이지로 바뀌어야하는데, 밑으로 누적되서 나온다.

1페이지를 지워주고 2페이지가 보이도록하려면 ?

tbody.innerHTML = ""; tbody의 자식들을 지운다.

 

Q. 데이터가 요청된 후에 지워져야하므로 

onload안에서한다. 

 

Q. 검색기능추가

NoticeList.java에 필드(검색종류), 쿼리(검색내용) 변수를 넣는다.

변수들이 null 그리고 빈문자열이 아닐때 변수에 담아 getList에 넣고 전달한다.

 

작업중이라는것을 알리면서, 다른요청을 또 하지않도록

명령할수있는버튼을 다 가리기

 

align-itemscenter;

그리드내에서의 아이템 수직정렬

수직축 : align/ 아이템 : item

align-itemscenter;


box-sizingborder-box;

콘텐트에 높이 90px

그리드에서 height90px + padding 5px 주면 박스가 커진다. (패딩을주면 박스가깬다)

콘텐트는 90이고 패딩이 5px로 늘어나서 박스자체가 커진다.

높이가 총 102으로 늘어남 (아이템 90 + 패딩 5 + 5 + border 1 + 1 )

box-sizingborder-box; 을 넣으면 박스 90준것이 유지된다


사용자가

1.목록페이지를 본다

2. 클릭하면 자세한내용이 나온다 (detail.jsp) 

3. 자세한페이지에 수정버튼, 삭제버튼이있다

 

제목,내용 수정할 수있게해보자.

수정할 수있는 상태를만들기

id에 해당하는 수정페이지

detail.jsp

detail.jsp를 복사한다.

제목 value에 자바코드를 넣는다.

내용 textarea태그를 만들고 안에 콘텐트를 불러온다.

<td colspan="3"><input type ="text" name="title"value="<%=notice.getTitle() %>"></td>
<tr>
<td colspan="4">
<textarea rows="20" cols="80"><%=notice.getContent() %></textarea>
</td>
</tr>

edit.jsp

<%=id%>

detail.jsp?id=<%=notice.getId()%>">취소</a>


sendRedirect

서블릿이 다른 서블릿을 요청할 수있게한다.

사용자가 저장을 눌러서 '업데이트처리'한테 post했지만 detail.jsp를 사용자에게 돌려준다.

 

jsp로만들면 <%%>코드블럭부담 + 제스퍼이용, 업데이트는 서블릿으로하는게 낫다

디테일jsp에 출력기능이 다있다. redirect로 detail.jsp에게 출력기능을 부탁한다.

 

  • 새로운패키지생성 controller.lecture
  • EditController 클래스생성
  • edit.jsp에서 보낸 <form action="edit" method="post"> , <textarea rows="20" cols="80"><%=notice.getContent() %></textarea>를 받을수 있게 준비한다.
  • name = "title"을 넣어 value="" 가 전달되게한다.
  • <textarea>태그에도 name을 넣는다

id는 자바스크립트로 값에 접근하는데 사용,

name은 jsp에서는 request.getparameter(name); 이렇게 값에 접근

editcontroller / edit

업데이트시 특정레코드만 수정하는거니까 id가 필요하다.

edit.jsp에 <input>태그에 숨겨서 보낼 수있다.

<input type="hidden"name="id" value="<%=id%>">


service.get(id);

editController.java

 

NoticeService.java

  • NoticeSerive.java에 update(Notice notice) 메소드 생성
  • 제목,내용,조회수,첨부파일 등  업데이트가 될 수있다.
  • sql을 한문장으로 쓸 수있게한다. 범용으로 쓸 수있는 update().
  • service.get(id);를 통해 해당id에 대한 데이터를 채워놓은상태에서 title,content를 다른값으로  대체할수있다.
notice = service.get(id);

조회수만 업데이트된다면 나머지는 null값을 가진다. -> 데이터를 DB에서 가져와서 업데이트한것만 바꾼다음에 널을 채운다. (sql에 업데이트 가능한것들을 한번에 나열)

수정할 것만 채워서 전달하면 나머지는 null이 채워지고 ->업데이트 후 기존데이터가 null이 된다.

넘겨지지않은 부분을 채워야한다.

So, EditController클래스에서

Notice notice = new Notice();로 새로운 객체를 생성하지말고

Notice notice = service.get(id);로 기존의 데이터를 가져온다.

 

+ Recent posts