반응형

< 전체 과정 >

로그인 -> 이메일 -> 비밀번호 -> 확인

 

 

1. 프로그램 실행

npm run dev

-> server와 client 모두 실행, client의 LandingPage가 로드된다.

 

 

2. LandingPage 디자인 수정

 

<div style={{
            display: 'flex', justifyContent: 'center', alignItems: 'center',
            width: '100%', height: '100vh'
}}>
     <h2>시작 페이지</h2>
</div>

 

 

- 페이지 새로고침 방지

event.preventDefault()

 

 

 

 

3. Redux를 이용한 LoginPage

 

import React, {useState} from 'react'
import {useDispatch} from 'react-redux';
import {loginUser} from '../../../_actions/user_action'

function LoginPage(props){
    const dispatch = useDispatch();

    const [Email, setEmail] = useState("")
    const [Password, setPassword] = useState("")
    const onEmailHandler = (event) => {
        setEmail(event.currentTarget.value)
    } 
    const onPasswordHandler = (event) => {
        setPassword(event.currentTarget.value)
    }
    const onSubmitHandler = (event) => {
        event.preventDefault()

        let body = {
            email: Email,
            password: Password
        }

        dispatch(loginUser(body))
        .then(response => {
            if(response.payload.loginSuccess){
                props.history.push('/');
            } else {
                alert('Error ');
            }
        })
    }


    return (
        <div style={{
            display: 'flex', justifyContent: 'center', alignItems: 'center',
            width: '100%', height: '100vh'
        }}>
            <form style={{ display: 'flex', flexDirection: 'column'}}
                onSubmit={onSubmitHandler}
            >
                <label>Email</label>
                <input type="email" value={Email} onChange={onEmailHandler}/>
                <label>Password</label>
                <input type="password" value={Password} onChange={onPasswordHandler}/>

                <br />
                <button>
                    Login
                </button>
            </form>
        </div>
    )
}

export default LoginPage

LoginPage.js

 

 

 

 

4. user_reducer 만들어주기

 

import {
    LOGIN_USER
} from '../_actions/types';

export default function (state = {}, action) {
    switch (action.type) {
        case LOGIN_USER:
            return { ...state, loginSuccess: action.payload }
    
        default:
            return state;
    }
}

user_reducer.js

 

 

-> 로그인 성공 시, loginSuccess가 뜨도록 해준다.

 

 

app.post('/api/users/login',(req, res) => {

  // 요청된 이메일은 데이터베이스에서 있는지 찾는다.
  User.findOne({ email: req.body.email }, (err, user) => {
    console.log(err)
    if(!user){
      return res.json({
        loginSuccess: false,
        message: "제공된 이메일에 해당하는 유저가 없습니다."
      })
    }
    // 요청된 이메일이 데이버테이스에 있다면, 비밀번호가 맞는 비번인지 확인한다.
    user.comparePassword(req.body.password, (err, isMatch) => {
      console.log(err)
      if(!isMatch) 
          return res.json({ loginSuccess: false, message: "비밀번호가 틀렸습니다."})

      // 비밀번호까지 맞다면 토큰을 생성하기
      user.generateToken((err, user) => {
        console.log(err)
        if(err) return res.status(400).send(err);

        // 토큰을 저장한다. 어디에?  쿠키, 로컬스토리지
        res.cookie("x_auth", user.token)  
        .status(200)
        .json({ loginSuccess: true, userId: user._id ,message: "비밀번호가 맞았습니다."})

      })
    })
  })
})

index.js(server)

 

 

-> 전에 index.js에서 설정해준 정보들이 나타난다.

 

 

 

5. reducers 안에 reducer를 관리하는 index.js 를 생성해준다.

 

import { combineReducers } from 'redux';
import user from './user_reducer';

const rootReducer = combineReducers({
    user
})

export default rootReducer;

index.js

 

-> reducer들은 여기에서 가져와서 사용하기로 한다.

 

 

 

 

6. user_action 만들기

 

import axios from 'axios';
import {
    LOGIN_USER
} from './types';
export function loginUser(dataTosubmit){
    const request = axios.post('/api/users/login', dataTosubmit)
        .then(response => response.data)

    return {
        type: LOGIN_USER,
        payload: request
    }
}

user_action.js

 

-> login action을 생성해준다.

 

 

 

 

6. 크롬에서 확인

 

Redux DevTools 라는 크롬 익스텐션을 설치해서

로그인 후 loginSuccess 가 뜨는지 확인한다.

 

반응형

'Programming > MERN' 카테고리의 다른 글

HTML 정리  (0) 2020.12.22
! 인증 체크하기 !  (0) 2020.11.10
Node.js 와 스프링의 차이 🤫  (0) 2020.11.10
🌺 회원가입 페이지 만들기 🌺  (0) 2020.11.09
CSS Framework / Redux 개념 및 설정  (0) 2020.11.02
반응형

< CSS Framework >

CSS Framework 종류 for React

1. Material UI -> 사용하기 어렵다.

2. React Bootstrap

3. Semantic UI

4. Ant Design 

5. Materialize

 

 

Ant Design을 사용할 것이다.

장점)

디자인이 깔끔하다.

Enterprise 환경에서도 잘 어울리는 디자인

쓰기가 용이하다.

 

단점)

용량이 매우 크다.

 

 

 

 

 

 

Ant Design 홈페이지에 가서 getting-started 따라한다.

 

ant.design/docs/react/introduce

 

Ant Design of React - Ant Design

Polyfills are needed for IE browsers. We recommend @babel/preset-env for it. You can set targets config if you are using umi. We recommend using npm or yarn to install, it not only makes development easier, but also allow you to take advantage of the rich

ant.design

 

 

 

비주얼 스튜디오 코드 Terminal에서

cd client
npm install antd --save

 

client/src/index.js에

import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'

 

하면 설정 끝.

 

 

 

 

 

 

 

 

 

< Redux 이론 >

 

Redux란? 상태 관리 라이브러리

 

Prop vs State

 

1) Prop

: Properties의 약자

: 컴포넌트 간에 데이터를 주고받을 때 사용

: 부모 컴포넌트에서 자식 컴포넌트로만 보낼 수 있다.

: 부모 컴포넌트에게 받은 데이터를 자식 컴포넌트가 변경할 수 없다. 바꾸려면 다시 부모 컴포넌트에게 다른 값을 받아야한다.

 

 

2) State

: 부모, 자식 간의 그런 관계가 아니고, 컴포넌트 간의 데이터를 전달하는 방법이다.

: 따라서 받은 데이터를 변경할 수 있다.

: State에서 값을 변경하면 re-rendering 되는 효과가 있다.

: 예를 들어, 검색창에 글을 입력할 때 글이 변하는 것은 state를 이용한 것이다.

 

이러한 State를 관리하는 것이 Redux 이다.

 

 

 

 

 

 

 

모든 컴포넌트는 Comment를 가지고 관리하고 있다.

그리고 부모 컴포넌트는 자식 컴포넌트의 Comment도 관리하고 있다.

이 때, Redux가 자식 컴포넌트 Comment의 변화를 부모 컴포넌트에게 한번에 전달하는 역할을 한다.

아래 그립과 같이, Redux Store에 넣어놓고

 

 

 

 

 

 

 

 

 

 

< Redux 실전 >

 

1. 다운받아야 하는 dependencies

1) redux

2) redux - thunk

3) redux - promise

4) react - redux

 

3)과 4) 리덕스를 더 잘 사용할 수 있도록 도와주는 미들웨어이다.

 

npm install redux react-redux redux-promise redux-thunk --save

 

 

 

2. import

 

import { Provider } from 'react-redux';
import { applyMiddleware, createStore } from 'redux';
import promiseMiddleware from 'redux-promise'
import ReduxThunk from 'redux-thunk';
import Reducer from './_reducers';

 

 

 

 

3. middleware

 

const createStoreWithMiddleware = applyMiddleware(promiseMiddleware, ReduxThunk)(createStore)

 

 

 

 

4. store

 

- 크롬 익스텐션 Redux DevTools 설치 후

ReactDOM.render(
    <Provider
        store={createStoreWithMiddleware(Reducer,
            window.__REDUX_DEVTOOLS_EXTENSION__ && 
            window.__REDUX_DEVTOOLS_EXTENSION__()
        )}
    >
        <App />
    </Provider>
, document.getElementById('root'));

 

 

 

 

5. _reducers 파일 밑에 index.js 파일 생성

 

import { combineReducers } from 'redux';
// import user from './user_reducer';

const rootReducer = combineReducers({
    // user,
})

export default rootReducer;

 

 

 

 

 

 

 

 

반응형
반응형

 

Q. BFS 모든 경로의 거리를 구하시오

 

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#define MAX_SIZE 101
using namespace std;

int ch[MAX_SIZE], dis[MAX_SIZE];

int main(void) {
    int n, m, a, b, x;
    
    vector<int> map[MAX_SIZE];
    queue<int> Q;
    scanf("%d%d", &n, &m);  
    
    for(int i=1; i<=m; i++){
        scanf("%d%d", &a, &b);
        map[a].push_back(b);
        map[b].push_back(a);
    }
    
    Q.push(1);
    ch[1] = 1;
    
    while(!Q.empty()){
        x=Q.front();
        Q.pop();
        for(int i=0; i<map[x].size(); i++){
            if(ch[map[x][i]] == 0){
                ch[map[x][i]] = 1;
                Q.push(map[x][i]);
                dis[map[x][i]] = dis[x] + 1;
            }
        }
    }
    for(int i=2;i<=n;i++){
        printf("%d : %d\n", i, dis[i]);
    }
    
    return 0;
}

 

 

- BFS는 큐를 사용하여 구현한다.

 

< 원리 >

1. 첫 번째 정점과 연결되어 있는 모든 정점을 확인

2. 해당 정점을 이전에 방문하지 않았을 경우 큐에 넣는다.

3. 1, 2번을 모두 완료한 후, 큐에서 그 다음 정점을 꺼내어 똑같은 과정을 반복한다.

 

 

 

 

 

 

응용문제1) 백준 1260 중 BFS

www.acmicpc.net/problem/1260

 

1260번: DFS와 BFS

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사

www.acmicpc.net

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

int ch[30], dis[30];        // ch는 방문했는지 안했는지

int main(void) {
    int n, m, a, b, x, start;
    
    vector<int> map[30];
    queue<int> Q;
    scanf("%d%d%d", &n, &m, &start);
    
    for(int i=1; i<=m; i++){
        scanf("%d%d", &a, &b);
        map[a].push_back(b);
        map[b].push_back(a);
    }
    
    // 작은 수부터 조건이 있으니까 정렬해주기
    for(int i=1; i<=n; i++){
        sort(map[i].begin(), map[i].end());
    }
    
    Q.push(start);
    ch[start] = 1;
    
    while(!Q.empty()){
        printf("%d ", Q.front());
        x = Q.front();
        Q.pop();
        
        for(int i=0; i<map[x].size(); i++){
            
            if(ch[map[x][i]] == 0){
                ch[map[x][i]] = 1;
                Q.push(map[x][i]);
            }
        }
    }
    return 0;
}

 

 

 

 

- 작은 수부터 먼저 탐색하라는 문제의 조건이 있으므로 정렬을 해준다.

- 1 대신 start 값을 받아서 시작 정점을 정해준다.

- BFS를 수행한다.

 

 

 

 

응용문제2) 백준 2606 바이러스

www.acmicpc.net/problem/2606

 

2606번: 바이러스

첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어

www.acmicpc.net

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int ch[101];

int main(void) {
    int n, m, a, b, x, cnt = 0;
    
    vector<int> map[101];
    queue<int> Q;
    scanf("%d%d", &n, &m);      // 두 줄에 나눠서 입력해도 가능한가? 가능!
    
    for(int i=1; i<=m; i++){
        scanf("%d%d", &a, &b);
        map[a].push_back(b);
        map[b].push_back(a);
    }
    
    Q.push(1);
    ch[1] = 1;
    
    while(!Q.empty()){
        x=Q.front();
        Q.pop();
        for(int i=0; i<map[x].size(); i++){
            if(ch[map[x][i]] == 0){
                ch[map[x][i]] = 1;
                Q.push(map[x][i]);
                cnt++;
            }
        }
    }
    printf("%d\n", cnt);
    
    return 0;
}

 

 

- 거리 대신 방문횟수를 구해야 하므로 cnt 변수를 넣어주고, 방문할 때마다 하나씩 증가하도록 했다.

- 배열 ch와 벡터배열 map 의 크기를 문제에 맞추어 101로 증가시켰다.

 

 

 

 

 

 

응용문제3) 백준 2644 촌수계산

www.acmicpc.net/problem/2644

 

2644번: 촌수계산

사람들은 1, 2, 3, …, n (1≤n≤100)의 연속된 번호로 각각 표시된다. 입력 파일의 첫째 줄에는 전체 사람의 수 n이 주어지고, 둘째 줄에는 촌수를 계산해야 하는 서로 다른 두 사람의 번호가 주어진

www.acmicpc.net

 

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int ch[101], dis[101];
int s, f;

int main(void) {
    int n, m, a, b, x;
    
    vector<int> map[101];
    queue<int> Q;
    scanf("%d", &n);
    scanf("%d%d", &s, &f);
    scanf("%d", &m);
    
    
    for(int i=1; i<=m; i++){
        scanf("%d%d", &a, &b);
        map[a].push_back(b);
        map[b].push_back(a);
    }
    
    Q.push(s);
    ch[s] = 1;
    
    while(!Q.empty()){
        x=Q.front();
        if(x == f)
            break;
        Q.pop();
        for(int i=0; i<map[x].size(); i++){
            if(ch[map[x][i]] == 0){
                ch[map[x][i]] = 1;
                Q.push(map[x][i]);
                dis[map[x][i]] = dis[x] + 1;
            }
        }
    }
    
    if(dis[f] == 0)
        dis[f] = -1;
    printf("%d\n", dis[f]);
    
    return 0;
}

 

- 배열 ch, dis와 벡터배열 map 의 크기를 문제에 맞추어 101로 증가시켰다.

- 시작노드와 마지막노드를 받아서 시작 노드부터 출발을 하였고, 마지막노드가 나왔을 때 break; 해 주었다.

- 관계가 아예 없다면(dis[f] == 0) -1을 출력하도록 하였다.

반응형
반응형

 

 

 

Q. DFS 로 갈 수 있는 모든 경로의 수는?

 

#include <stdio.h>
#include <iostream>
using namespace std;

int map[30][30], ch[30], cnt = 0;
int n, m;

void DFS(int v){            // v -> 정점 번호
    if(v == n) {
        cnt++;
    }
    else {
        for(int i=1; i<=n; i++){
            if(map[v][i] == 1 && ch[i] == 0){
                ch[i] = 1;                          // 한 번 길 갈 때, 똑같은 곳을 또 방문하지 않기 위해
                DFS(i);
                ch[i] = 0;
            }
        }
    }
}

int main(void) {
    int a, b;
    
    scanf("%d%d", &n, &m);
    
    for(int i=0; i<m; i++){
        scanf("%d%d",&a,&b);
        map[a][b] = 1;
    }
    ch[1] = 1;
    DFS(1);
    printf("%d\n", cnt);
    
    return 0;
}
​

 

n = 정점의 개수, m = 간선의 개수

 

 

 

 

 

 

 

 

 

 

응용 문제) 백준 1260

 

www.acmicpc.net/problem/1260

 

1260번: DFS와 BFS

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사

www.acmicpc.net

 

#include <stdio.h>
#include <iostream>
using namespace std;

int map[30][30], ch[30], cnt = 0;
int n, m, start;

void DFS(int v){            // v -> 정점 번호
    printf("%d ", v);
    
    if(cnt == n) {
        return;
    }
    else {
        for(int i=1; i<=n; i++){
            if(map[v][i] == 1 && ch[i] == 0){
                cnt++;
                ch[i] = 1;                          // 한 번 길 갈 때, 똑같은 곳을 또 방문하지 않기 위해
                DFS(i);
            }
        }
    }
}

int main(void) {
    int a, b;
    
    scanf("%d%d%d", &n, &m, &start);
    
    for(int i=0; i<m; i++){
        scanf("%d%d",&a,&b);
        map[a][b] = 1;
        map[b][a] = 1;
    }
    
    ch[start] = 1;
    cnt++;
    DFS(start);
    
    return 0;
}

 

 

 

- map[a][b] 만이 아닌, map[b][a]도 1로 설정

- 시작 정점을 1이 아닌, 값을 받아서 주고,

- 여러 경로를 탐색하기 위해 ch[i] = 0; 으로 풀어주는 과정을 지웠다.

 

 

 

 

 

 

 

 

 

 

 

 

응용문제) 백준 10971

www.acmicpc.net/problem/10971

 

10971번: 외판원 순회 2

첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 10) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j

www.acmicpc.net

 

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int W[11][11];
int visited[11];

int N;
int start;
long long int m = 98765432;

void dfs(int start, int n, int cost, int cnt){
    
    // 선택한 노드의 수가 총 개수이고, 시작 노드까지의 경로가 있으면
    if(cnt == (N-1) && W[n][start] != 0){
        cost += W[n][start];
        if(cost < m)
            m = cost;
        return;
    } else {
        for(int i=0; i<N; i++){
            
            if(n == i || W[n][i] == 0)
                continue;
            
            // 간 적이 없는 노드일 때
            if(visited[i] == 0){
                
                visited[i] = 1;
                dfs(start, i, cost + W[n][i], cnt+1);
                visited[i] = 0;
            }
        }
    }
}


int main(void) {

    scanf("%d", &N);
    
    for(int i=0; i<N; i++){
        for(int j=0; j<N; j++){
            scanf("%d", &W[i][j]);
        }
    }

    // 0에서 출발하는 것만 구해도 됨 -> 싸이클이 있기 때문에 다른 출발점으로 해도 동일함
    visited[0] = 1;
    dfs(0, 0, 0, 0);
    
    printf("%lld\n", m);
    
    return 0;
}

 

 

- 최소 비용 경로를 구하는 문제였음

- DFS 재귀 반복할 때마다 cost와 cnt 를 넣어주고, 나올 때는 다시 풀게 하여 모든 경우의 cost 와 cnt를 구할 수 있게 함

 

 

 

 

 

 

반응형
반응형

1. 저급언어

 

0과 1로 이루어진 언어, 기계어라고 부른다.

0과 1로만 되어있으면 해석하기 어렵기 때문에 이를 기호로 만들어 프로그래밍하게 되었다. 어셈블리어 라고 한다.

단, 이 어셈블리어는 컴퓨터가 바로 알아들을 수 없어서 기호를 원래의 숫자로 되돌리는 컴파일러가 필요하게 되었다.

 

 

 

2. 고급언어

 

사람 중심의 언어이다.

사람이 이해하기 쉬운 문법으로 작성된 소스 코드를 컴파일러가 번역하여 컴퓨터에게 전달한다.

앞서 언급한 기호를 숫자로 돌리는 컴파일러와 동일하다.

 

 

 

 

3. HTTP 작동방식

 

HTTP는 서버/클라이언트 모델을 따른다.

  • 장점
    - 불특정 다수를 대상으로 하는 서비스에는 적합하다.
    - 클라이언트와 서버가 계속 연결된 형태가 아니기 때문에 클라이언트와 서버 간의 최대 연결 수보다 훨씬 많은 요청과 응답을 처리할 수 있다.
  • 단점
    - 연결을 끊어버리기 때문에, 클라이언트의 이전 상황을 알 수가 없다.
    - 이러한 특징을 무상태(Stateless)라고 말한다.
    - 이러한 특징 때문에 정보를 유지하기 위해서 Cookie와 같은 기술이 등장하게 되었다.

 

 

4. URL (Uniform Resource Locator)

  • 인터넷 상의 자원의 위치
  • 특정 웹 서버의 특정 파일에 접근하기 위한 경로 혹은 주소

 

 

5. HTTP (Hypertext Transfer Protocol)

HTTP는 서버와 클라이언트가 인터넷상에서 데이터를 주고받기 위한 프로토콜(protocol)

 

  • 요청 메서드 : GET, PUT, POST, PUSH, OPTIONS 등의 요청 방식이 온다.
  • 요청 URI : 요청하는 자원의 위치를 명시한다.
  • HTTP 프로토콜 버전 : 웹 브라우저가 사용하는 프로토콜 버전이다.

첫번째 줄의 요청메소드는 서버에게 요청의 종류를 알려주기 위해서 사용됩니다.

각각의 메소드 이름은 다음과 같은 의미를 가집니다.

참고로 최초의 웹 서버는 GET방식만 지원해줬습니다.

  • GET : 정보를 요청하기 위해서 사용한다. (SELECT)
  • POST : 정보를 밀어넣기 위해서 사용한다. (INSERT)
  • PUT : 정보를 업데이트하기 위해서 사용한다. (UPDATE)
  • DELETE : 정보를 삭제하기 위해서 사용한다. (DELETE)
  • HEAD : (HTTP)헤더 정보만 요청한다. 해당 자원이 존재하는지 혹은 서버에 문제가 없는지를 확인하기 위해서 사용한다.
  • OPTIONS : 웹서버가 지원하는 메서드의 종류를 요청한다.
  • TRACE : 클라이언트의 요청을 그대로 반환한다. 예컨데 echo 서비스로 서버 상태를 확인하기 위한 목적으로 주로 사용한다.

 

 

 

6. 미들웨어 (MiddleWare)

클라이언트 쪽에 비즈니스 로직이 많을 경우, 클라이언트 관리(배포 등)로 인해 비용이 많이 발생하는 문제가 있습니다.

비즈니스 로직을 클라이언트와 DBMS사이의 미들웨어 서버에서 동작하도록 함으로써 클라이언트는 입력과 출력만 담당하도록 합니다.

 

 

 

 

 

 

7. WAS (Web Application Server)

WAS는 일종의 미들웨어웹 클라이언트(보통 웹 브라우저)의 요청 중 웹 애플리케이션이 동작하도록 지원하는 목적을 가집니다.

 

 

 

8. 웹 서버란?

  • 웹 서버는 소프트웨어(Software)를 보통 말하지만, 웹 서버 소프트웨어가 동작하는 컴퓨터를 말합니다.
  • 웹 서버의 가장 중요한 기능은 클라이언트(Client)가 요청하는 HTML 문서나 각종 리소스(Resource)를 전달하는 것입니다.
  • 웹 브라우저나 웹 크롤러가 요청하는 리소스는 컴퓨터에 저장된 정적(static)인 데이터이거나 동적인 결과가 될 수 있습니다.

 

 

 

웹 서버 소프트웨어의 종류

  • 가장 많이 사용하는 웹 서버는 Apache, Nginx, Microsoft IIS
  • Apache웹 서버는 Apache Software Foundation에서 개발한 웹서버로 오픈소스 소프트웨어(Open-source Software)이며, 거의 대부분 운영체제에서 설치 및 사용을 할 수 있습니다.
  • Nginx는 차세대 웹서버로 불리며 더 적은 자원으로 더 빠르게 데이터를 서비스하는 것을 목적으로 만들어진 서버이며 Apache웹 서버와 마찬가지로 오픈소스 소프트웨어입니다.

 

 

 

 

웹 서버 vs WAS

  • WAS도 보통 자체적으로 웹 서버 기능을 내장하고 있습니다.
  • 현재는 WAS가 가지고 있는 웹 서버도 정적인 콘텐츠를 처리하는 데 있어서 성능상 큰 차이가 없습니다.
  • 규모가 커질수록 웹 서버와 WAS를 분리합니다.
  • 자원 이용의 효율성 및 장애 극복, 배포 및 유지보수의 편의성을 위해 웹서버와 WAS를 대체로 분리합니다.
반응형
반응형

JDBC란? (Java Database Connectivity)

- 자바 프로그램 내에서 SQL문을 실행하기 위한 자바 API

 

즉, DB와 자바 프로그램을 연결시켜주는 연결 다리의 역할을 한다는 것이다.

 

 

JDBC 클래스 생성 관계

 

 

 

 

SELECT DAO 예제

public Role getRole(String name) {

	Role role = null;
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;

	try {
		Class.forName("com.mysql.jdbc.Driver");
		conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
		String sql = "SELECT name, tel FROM card WHERE name = ?";
		ps = conn.prepareStatement(sql);
		
		ps.setString(1, name);
		
		rs = ps.executeQuery();            // select는 executeQuery() 이용
										   // ResultSet type의 변수에 결과 입력

		if (rs.next()) {
			String name1 = rs.getString("name");
			String tel1 = rs.getString("tel");
			role = new Role(name1, tel1);
		}
	} catch (Exception e) {
		e.printStackTrace();
	} 
	finally {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	return role;
}

 

 

 

 

INSERT DAO 예제

public int addRole(Role role) {

	int insertCount = 0;
	Connection conn = null;
	PreparedStatement ps = null;

	try {
		Class.forName("com.mysql.jdbc.Driver");
		conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
		String sql = "INSERT INTO card (name, tel) VALUES ( ?, ? )";
		ps = conn.prepareStatement(sql);
	
		ps.setString(1, role.getName());
		ps.setString(2, role.getTel());

		insertCount = ps.executeUpdate();	// insert, delete, update는 executeUpdate() 이용
											// int type 변수에 결과 입력
	} catch (Exception ex) {
		ex.printStackTrace();
	} finally {
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	return insertCount;
}

 

 

 

 

 

DELETE DAO 예제

public int deleteRole(Integer roleId) {

	int insertCount = 0;
	Connection conn = null;
	PreparedStatement ps = null;

	try {
		Class.forName("com.mysql.jdbc.Driver");
		conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
		String sql = "DELETE from role where role_id = ?";
		ps = conn.prepareStatement(sql);
	
		ps.setInt(1, roleId);

		insertCount = ps.executeUpdate();	// insert, delete, update는 executeUpdate() 이용
											// int type 변수에 결과 입력
	} catch (Exception ex) {
		ex.printStackTrace();
	} finally {
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	return insertCount;
}

 

 

 

 

UPDATE DAO 예제

public int updateRole(Role role) {

	int insertCount = 0;
	Connection conn = null;
	PreparedStatement ps = null;

	try {
		Class.forName("com.mysql.jdbc.Driver");
		conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
		String sql = "UPDATE role set description = ? where role_id = ?";
		ps = conn.prepareStatement(sql);
	
		ps.setString(1, role.getDescription());
		ps.setInt(2, role.getRoleId());

		insertCount = ps.executeUpdate();	// insert, delete, update는 executeUpdate() 이용
											// int type 변수에 결과 입력
	} catch (Exception ex) {
		ex.printStackTrace();
	} finally {
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	return insertCount;
}

 

 

DriverManager를 이용해 connection을 가져오고,

conn 객체를 이용해 statement를 가져오고,

statement를 통해 ResultSet을 가져옴을 확인할 수 있다.

 

 

 

 

 

 

JSP란?  (java server page)

 

 

JSTL이란? (JSP Standard Tag Library)

- JSTL은 JSP 페이지에서 조건문 처리, 반복문 처리 등을 html tag형태로 작성할 수 있게 도와준다.

 

JSP 페이지에서 자바 언어와 프론트엔드 언어가 섞여있으면 다루기 힘드니까, 자바 언어를 html tag 형태로 작성할 수 있도록 도와주는 것이다.

 

 

서블릿이란?

반응형

+ Recent posts