본문 바로가기
학원수업/2월

02/21 58회차

by 코딩마스터^^ 2023. 2. 21.

쿠키는 문자열만 관리된다. 텍스트만 가능.

텍스트와 바이너리는 다르다.

 

서블릿에서 자바로 자바에서 마이바티스통해 오라클에 연동.

Dao라는 이름으로 데이터 연결 관리. 데이터 엑세스 오브젝트의 약자이다.

요청은 뷰를 통해서 받지만 응답은 같은 페이지일수도 다른 페이지 일수도 있다.

 

outer join으로 없는 쪽을 널로 하고 다 나오게 한다...

 

sendRedirect VS forward

requestDispatcher

req.getDispatcher

 

오라클서버를 경유하기 위해서는 응답페이지인 list.jsp가 받음

서블릿은 응답을 처리해주는 

리쿼스트 아니먄 세션에 담아야한다.

휘발성이 강해서 날아간다.

리쿼스트에 리스트나 맵을 저장한다,

 

리스트.jsp에 응답 책임까지 넘어간다.

 

계층형 게시판 문제

 

1. 게시글 목록 페이지를 열때 오라클 서버를 경유하여 최신글 10건을 가져온다.

출력은 내림차순으로 정렬하여 출력해준다.

 

2. 제목을 클릭하면 상세보기 페이지로 이동하기 전에 오라클 서버를 경유하여 사용자가 선택한 제목에 대한 한건의 정보만 가져와서 read.jsp에 출력한다.

1번에서 제목을 클릭할때 글 번호를 서블릿에 넘겨서 select문 where절에 조건값으로 사용함

 

3.댓글쓰기 버튼을 누르면 상세보기 페이지에서는 글번호 글그룹번호, 차수, 순번, 글제목 등 1번에서 선택된 글번호에 

해당하는 모든 정보를 가지고 있으므로 글 내용을 입력받아 폼 전송시에 댓글쓰기에 필요한 정보인 글번호, 차수, 숭번을 반드시 넘겨준다.

위에서 가져온 글 번호는 새글쓰기인지 댓글쓰기인지를 판별하는 용도로 사용하면 됨

 

댓글 쓰기 버튼은 상세보기에 있다. 목록버튼에 있는 글쓰기 버튼은 새글쓰기이고 채번이 아직 안됐다.

글번호는 유니크해야된다. 

새글쓰기일때 bm_no 채번한다.

bm_pos는 0으로 한다.

bm_step도 0으로 한다.

댓글쓰기일때

bm_no는 채번한다,

bm_group은 가져온 값으로 추가

bm_group은 가져온 값으로 추가->read.jsp=->댓글쓰기.

내가쓰는 댓글뒤에 댓글이 존재하는 경우만 실행된다.

조건절에 들어오는 그룹번호와 step은 상세보기 화면에서 가져온 값이 대입되면 된다.

첨부파일을 추가하는 경우에만 실행된다.

없으면 해당없음

글번호는 새글쓰기에서 결정된 값이 대입되어야함.

 

새글을 쓸때 bm_pos와 bm_step은 원글이면 0,0으로 입력하고

댓글이면 read.js에서 가진 값에 각각 1을 더한 값으로 결정된다.

조회수는 0으로 하면 되고 날짜는 시스템 날짜 정보로 등록

 

4. 상세보기에서 글 수정을 누르면 기본 정보를 출력하고 사용자가 선택하여 수정받도록 처리한다.

수정의 범위는 정해야 한다.

단, 수정의 경우 비번을 입력 받아서 일치하는 경우에만 수정처리를 해준다.

 

5. 상세보기에서 글 삭제를 누르면 정말 삭제하시겠습니까>? 라고 다이얼 로그 창으로 물어보고 비번이 일치하면 삭제 처리한다.

공통사항

비번은 언제 어떻게 어디서 비교 할까요??

상세보기에서 비번을 미리 가지고 있도록 한다.

화면에는 보이지 않아야 한다.

<iput type="hidden">

 

비번에 대한 비교는 자바로 한다. 아니다 자바 스크립트로 표현한다.

자바스크립트로 처리한다.

비번이 맞지 않으면 서버로 전달하지 않는게 효율적이다.

 

 

데이터 정규화

1정규화, 2정규화, 3정규화는 데이터베이스 설계에서 중복을 제거하고 데이터를 정리하는 과정을 말합니다. 이들 과정은 함수 종속성(functional dependency)이라는 개념을 바탕으로 수행됩니다.

 

1정규화

각 테이블이 원자적인 데이터만 포함하도록 만드는 과정입니다. 즉, 하나의 속성이 여러 개의 값을 가지고 있으면 이를 여러 개의 속성으로 분리하는 것을 의미합니다. 이를 통해 중복 데이터가 제거되고, 데이터의 일관성이 향상됩니다.

 

2정규화

1정규화를 거친 후, 부분 함수 종속성(partial functional dependency)을 제거하는 과정입니다. 부분 함수 종속성이란, 기본키(primary key)가 아닌 속성이 기본키의 일부분에만 종속되는 경우를 의미합니다. 이를 해결하기 위해서는 해당 속성을 별도의 테이블로 분리해야 합니다.

 

3정규화

2정규화를 거친 후, 이행 함수 종속성(transitive functional dependency)을 제거하는 과정입니다. 이행 함수 종속성이란, A -> B, B -> C와 같이 한 속성이 다른 속성에 종속되어 있을 때, A -> C와 같은 종속성이 성립되는 경우를 의미합니다. 이를 해결하기 위해서는 해당 속성을 별도의 테이블로 분리해야 합니다.

이들 정규화 과정은 데이터의 일관성과 정확성을 향상시키는 중요한 과정입니다. 그러나, 과도한 정규화는 성능 문제를 야기할 수 있으므로, 적절한 정규화 수준을 선택해야 합니다.

PK에만 종속되어야한다. 그러나 FK에 종속적인경우 제 3 정규화 필요하다.

 

 

카타시안의 곱=경우의 수

조인을 걸지 않는다.

 

 Frontcontroller라고 정했다. 요청을 제일 처음 받아주는것을...

doGet과 doPost있어야한다.

BoardController

getBoardList

getBoardDetail

getboardDetail

boardInsert

boardDelete

boardUpdate

 

클래스 설계

 

VSCode에서 Spring사용하기

 

propertise대신 yml을 사용하자.

같은 코드를 더욱 간단하게 설정할 수 있다.

 

WEB-INF는 src폴더에 있다. src폴더는 절대로 URL로 접근이 불가능 하다.

mvc패턴을 기반으로 하는 웹 개발에 있어서는 반드시 요청을 받아주는 페이지와 응답이 나가는 페이지가 분리 되어야 한다. 

요청을 받는것은 Servlet이다.

HttpServlet ------>스프링에서는 DispatchServlet

 

상속을 계속 받으므로 아들이 더 면적이 넚다. 누릴 수 있는 API가 많다. 누릴수 있는 클래스가 많다. 메소드와 변수가 많다.

 

GetMapping----->자바에서는 doGet

요청을 할때 사용하는 메소드이다.

 

localhost:7000/home/index

컨트롤러 즉, 서블릿을 요청하는 것이다. 응답은 index.jsp에서 나간다.

요청을 받는 쪽과 응답을 받는 쪽은 달라야한다.

 

서블릿에서 home/index라고 반환을 했다.

@Restcontroller  

---plain으로 나간다.

 

text/plain

text/html

applcation/jsp

text/xml

 

@Controller 

 

mvc

view

prefix  ---->접두어

suffix ------>접미어

위치경로를 붙여주는거다.

 

위치를 안맞춰주면 404번 에러가 뜬다. 조심하자!!!!!

 

 

바벨 1

<!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>바벨소개</title>
    <script
      crossorigin
      src="https://unpkg.com/react@18/umd/react.development.js"
      ></script>
      <!-- ES5와같은 버전에서도 동작하도록 지원받기 위해서 바벨도 주입 받음
      CDN방식 로컬PC캐쉬 사용함-시스템 사용 발생
    unpkg방식 네트워크 통해 객체 주입-속도 향상 -->
    <script
      crossorigin
      src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <!-- min의 의미는 공백이 없다는 뜻. 데이터를 아끼자^^ -->
    <!-- unpkg 빠륵 로딩시간이 덜 걸린다네요...  -->
  </head>
  <body>
    <!-- 아래 내부 노드에 리액트를 통해서 생산된 태그 들어옴 -->
    <div id="root"></div>
    <style>
      .title {
        color: rgb(219, 67, 219);
      }
    </style>
    <!-- babel이 타입이어야 리액트 코드로 자바스크립트를 컵파일 해준다. -->
    <script type="text/babel">
      //자바 스크립트에서 html노드를 접근하기 위해서 브라우저의 내장 객체인 도큐먼트는 querySelector를 지원 한다.
      const rootElement = document.querySelector("#root");//아이디인 경우 반드시 #을 붙여야된다.
      const element = React.createElement(//DOM생성하기 creatElement가 리액트에서 제공하는 함수
      //React에서 제공하는 createElement함수로 태그를 생성 가능함
      //스타일 추가시에는 반드시 class속성이 아니라 className으로 해야함 
      "h1",
        {/* css디자인 주기 */
          className: "title",
        },
        ["JAVA", "React", "Spring"]/* 배열 객체 h1의 자식들 */
      );
      ReactDOM.createRoot(rootElement).render(element);
      /* 리액드 돔은 루트 접근 위한것이다. create root해달라는 뜻. 위치는 root
      rendor함수가 그리는 담당. element를 그려라. */
    </script>
  </body>
</html>

 

바벨을 사용해서 서버 사용

 

해커뉴스에서 가져오기. 다음번에는 Spring에서 가져올듯...?

const HackerNews = (props) => { //{newsList:Array(30)}원래 이렇게 되어 있었다. 기존의 자바스크립트보다 훨씬 더 데이터 셋과의 연계가 자유롭다.}
  const {newsList}=props;
  /* console.log(props);
  console.log(props.newsList);->구조분해할당이 된다. */
  return (  
    <div>
      {/* [{},{}...] 맵으로 꺼낸다. */}
      {newsList && Object.keys(newsList).map(key=>( /* 태그 안에서 에로우 펑션은 () */
        <li>
          {newsList[key].id}/
          {newsList[key].title}/
          user : 👼{newsList[key].user}/
          comments_count : 👩‍🎓{newsList[key].comments_count}/
          time_ago:🧚‍♂️{newsList[key].time_ago}
         
        </li>
      ))}
    </div>
  );
}
 
export default HackerNews;
import axios from "axios";
import { useEffect, useState } from "react";
import HackerNews from "./components/HackerNews";

const HackerApp = () => {
  const [newsList,setNewsList]=useState([]);/* 배열은 [] 객체는{} */
  const NEWS_URL= "https://api.hnpwa.com/v0/news/1.json"; /* 이 자리에 jsp 스프링이 들어간다. */
  useEffect(()=>{
    axios.get(NEWS_URL).then(response=>{
      console.log(response.data)
      console.log(newsList);
      //6번에서 선언한 useState훅에 데이터 초기화함
      setNewsList(response.data)
    })
    }, [])
    return ( 
      <HackerNews newsList={newsList}/>
  );
}

export default HackerApp;
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import HackerApp from './HackerApp';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
 <>
{/*   <react.StrincMode>두번찍히게 한다.  <App /> */}
  <HackerApp/>
  {/* 태그를 만들어서 쓸 수 있다. 사용자 정의 태그 */}
  </>
);
/* HackerNews데이터를 axios가 가져올때 <react.StrincMode>있으면 두번 가져오니까 빈태그로 변경하였다.
여기서 빈 태그는 Fragment를 의미함*/

리액트써보기^^

<!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>element</title>
   <script
      crossorigin
      src="https://unpkg.com/react@18/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root">
    <h1>One</h1>
    <h1>Two</h1>
    <h1>Three</h1>
  </div>
 
    <script type="text/babel">
      const rootElement = document.querySelector("#root");
    const element=(
      <div className="box"
      children={
        [
          React.createElement("h1",null,"Zero"),
          /* null은 클래스 이름 css들어가는 자리 세번째는 자식. 하위태그가 오는 자리 */
          React.createElement("h1",null,"Two"),
          React.createElement("h1",null,"Tree")
      ]}/>
    );
      // const 사용자정의태그 = (
      //   <h1 className={props.className} children={props.children}></h1>
      // );
      ReactDOM.createRoot(rootElement).render(element);
    </script>

  
</body>
</html>

댓글