AC 03/25 node js

Bae Seong Jun·2024년 3월 25일

Acorn academy

목록 보기
60/70
post-thumbnail

node js

자료 pt 참고

node => 자바스크립트코드 => 브라우저 밖에서 실행되는 (애플리케이션)
: 웹서버 구축, db 연동

설치 및 설정

  1. 노드 폴더 생성 C:\node_study\node_stu
    node, npm 버전 확인

  2. 실행 node 파일명.js
    순수 js파일만 실행하는 것이라면 init도 필요 없음

express 라이브러리의 사용

라이브러리

express 라이브러리 사용

const express = require('express')
const app = express()

app.get('/', function (req, res) {
  res.send('Hello World')
})

app.listen(3000)

express 설치 -> node_modules 폴더가 생성되며 다운받은 파일들이 이 곳에 저장됨

간편단축키 : 터미널에서 node 작성후 우클릭하면 복사된 파일명 붙음

서버 실행

const express =require("express");
const app = express();
const server = app.listen(3000, ()=>{
    console.log("start server : localhosh : 3000");
}); 

주소처리

app.get("/about", function(req, res) {
    res.send("about page");
})

파일 랜더링 - ejs

ejs 라이브러리 필요

app.get("/", function(req, res) {
    res.render("views/index.html");
})

npm install ejs --save

//2. get방식 요청처리
// 라우터 처리 및 콜백함수 등록
app.set("views", __dirname + "/views"); //파일위치지정
app.set("view engine", "ejs"); //npm ejs 검색, jsp같이 html에 js코드를 같이 사용하게 함
//npm install ejs --save
app.engine("html", require("ejs").renderFile); //html파일 사용 설정
app.get("/", function(req, res){
    res.render("index.html");
});

app.get("/about", function(req, res){
    res.send("<h1>about page</h1>");
});

db연동

//참고 https://node-oracledb.readthedocs.io/en/latest/user_guide/initialization.html

npm install oracledb

dbconfig.js 생성

module.exports = {
    user: "scott",
    password: "tiger",
    xid: "localhost:1521/xe",
    externalAuth: false
}

쿼리문 밖에서 결과데이터 접근

select 쿼리의 결과물은 2차원배열로 준다.
비동기
2차원 배열은 column명까지 포함
data만 얻기 위해 .rows를 사용

app.get("/select", function (req, res){
    getSelection(req, res);
})

async function getSelection(req, res){
    let connection;
    try{
        connection = oracledb.getConnection({
            // user: "scott",
            // password: "tiger",
            // connectString: "localhost:1521/xe"
            user: dbconfig.user,
            password: dbconfig.password,
            connectString: dbconfig.xid,
        });

        //const result = (await connection).execute("select * from dept");
        const result = (await connection).execute(
            "select * from dept where deptno=:xxx", [10]
        );
        
        console.log(result);
        console.log("후:", result.rows);
        res.send((await result).rows); //2차원 배열과 내용
        console.log("후:", result);
        console.log("후:", (await result).rows);
    } catch(error){
        console.log(error);
    } finally{
        if(connection){
            try{
                (await connection).close;
            } catch(error){
                console.log("error", error);
            }
        }
    }
}

쿼리문 동적값 사용

sql 문에 변수값을 넣고 싶으면 쿼리문에 :xxx 처리한 후,
2번째 인자의 배열에 [1번값, 2번값] 형식으로 할당한다.

Promise : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise

await : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/await

쿼리문 콜백함수에서 데이터 관리

connection.execute("sql", 콜백함수(error, data));
콜백함수 내의 data는 {metaData:[{},{},{},{}], rows:[[],[],[]} 형식을 가짐
metaData는 column값들, rows배열 내의 각 배열은 하나의 row

{
  metaData: [
    {
      name: 'DEPTNO',
      dbType: [DbType DB_TYPE_NUMBER],
      nullable: false,
      isJson: false,
      isOson: false,
      precision: 2,
      scale: 0,
      dbTypeName: 'NUMBER',
      fetchType: [DbType DB_TYPE_NUMBER]
    },
    {
      name: 'DNAME',
      dbType: [DbType DB_TYPE_VARCHAR],
      nullable: true,
      isJson: false,
      isOson: false,
      byteSize: 14,
      dbTypeName: 'VARCHAR2',
      fetchType: [DbType DB_TYPE_VARCHAR]
    },
    {
      name: 'LOC',
      dbType: [DbType DB_TYPE_VARCHAR],
      nullable: true,
      isJson: false,
      isOson: false,
      byteSize: 13,
      dbTypeName: 'VARCHAR2',
      fetchType: [DbType DB_TYPE_VARCHAR]
    }
  ],
  rows: [
    [ 10, 'ACCOUNTING', 'NEW YORK' ],
    [ 20, 'RESEARCH', 'DALLAS' ],
    [ 30, 'SALES', 'CHICAGO' ],
    [ 40, 'OPERATIONS', 'BOSTON' ],
    [ 67, '흠흐밍', '화성' ],
    [ 77, '행운', 'ㅂㅊ' ],
    [ 14, '영업', '부산' ],
    [ 51, '51', '51' ],
    [ 12, 'aa', 'aa' ],
    [ 13, 'bb', 'bb' ]
  ]
}
const express = require("express");
const app = express();

// 서버 listen
const server = app.listen(3000, ()=>{
    console.log("Start Server: localhost:3000");
});


// __dirname: 현재 디렉토리
// page 경로 설정

app.set("views", __dirname + "/views");  //페이지 alias 설정
app.set("view engine", "ejs"); //view engine의 alias ejs로 설정
app.engine("html", require("ejs").renderFile);  // 

app.get("/", function(req, res){
    res.render("index2.html");
});

const oracledb = require("oracledb");
oracledb.initOracleClient();
const dbconfig = require("./dbconfig.js");

app.get("/select", function(req, res){
    getSelection(req, res);
});

async function getSelection(req, res){
    let connection;
    try{
        connection = oracledb.getConnection({
            // user: "scott",
            // password: "tiger",
            // connectString: "localhost:1521/xe"
            user: dbconfig.user,
            password: dbconfig.password,
            connectString: dbconfig.xid,
        });
        ///////////////
        const result = (await connection).execute(
            "select * from dept", //콜백함수
            function (error, data){
                console.log("실행됨");
                if(error){
                    console.log(error);
                }
                console.log("실행후 :", data);
                console.log("실행후 rows :", data.rows);
                res.send(data.rows); /////
            }
        );
    } catch(error){
        console.log(error);
    } finally{
        if(connection){
            try{
                (await connection).close;
            } catch(error){
                console.log("error", error);
            }
        }
    }
}

dml sql 구현

node - dml sql
기본 auto commit이 false
1. autocommit = true 설정
2. connection에 4가지 정보 입력
3. insert 문 실행, execute 함수 실행 -> insert후 자동 반영 -> 결과데이터처리 -> 응답
4. connection.close

콜백함수(에러, 결과)
결과에는 { lastRowid: 'AAAE5cAABAAALCJAAI', rowsAffected: 1 }
Rowid와 영향을 받은 행 갯수가 json 형식으로 반환됨

구현 실습

selectById
insert
update
delete

const express = require("express");
const app = express();

const server = app.listen(3000,()=>{
    console.log("Start Server: localhost:3000");
});

app.set("views", __dirname+"/views");
app.set("view engine", "ejs");
app.engine("html", require("ejs").renderFile);

const oracledb = require("oracledb");
oracledb.initOracleClient();

const dbconfig = require("./dbconfig");
app.get("/", (req, res)=>{
    res.render("index.html");
});

app.get("/select", (req, res)=>{
    getSelection(req, res);
});

app.get("/selectById", (req, res)=>{
    getSelectById(req, res);
})

app.get("/insert", (req, res)=>{
    getInsert(req, res);
})

async function getInsert(req, res){

    oracledb.autoCommit = true;

    let connection;
    try {
        // connection 정보 주입
        connection = oracledb.getConnection({
            user: dbconfig.user,
            password: dbconfig.password,
            connectString: dbconfig.xid
        });
    
        // 쿼리문 실행 / 콜백함수로 결과 데이터 처리
        const result = (await connection).execute(
            "insert into dept values (:deptno, :dname, :loc)",
            // "update dept set dname=:dname, loc=:loc where deptno=:deptno",
            // "delete from dept where deptno =:deptno",
            [99, "개발", "제주"],
            function(error, result){
                console.log("sql 결과처리 콜백함수 실행됨");
                if(error){
                    console.log("error", error);
                    res.send("중복된 부서입니다.");
                }
                console.log(result, result.rowsAffected);
                if(result.rowsAffected==1){
                    res.send("추가완료");
                }
            }
        );
        console.log("result", result);

        // 응답 데이터 전달
        res.send("실행완료");
    } catch (error) {
        console.log(error);
    } finally {
        //커넥션 닫기
        if(connection){
            try {
                (await connection).close;
            } catch (error) {
                console.log("error", error);
            }
            
        }
    }
}

async function getSelectById(req, res){
    let connection;
    try {
        connection = oracledb.getConnection({
            user: dbconfig.user,
            password: dbconfig.password,
            connectString: dbconfig.xid
        });

        const result = (await connection)
            .execute("select * from dept where deptno = :deptno order by deptno", [10]);

        
        res.send((await result).rows);
    } catch (error) {
        
    }
}

// oracledb에 연결하여 select * from dept 의 결과값을 받아 출력하는 함수
async function getSelection(req, res){
    let connection;
    try {
        connection = oracledb.getConnection({
            user: dbconfig.user,
            password: dbconfig.password,
            connectString: dbconfig.xid
        });

        const result = (await connection)
            .execute("select * from dept order by deptno");

        res.send((await result).rows);
    } catch (error) {
        
    }
}

테이블로 구현

문제점 : 코드작업량이 많아지며, 복잡함

const express = require("express");
const app = express();

const server = app.listen(3000,()=>{
    console.log("Start Server: localhost:3000");
});

app.set("views", __dirname+"/views");
app.set("view engine", "ejs");
app.engine("html", require("ejs").renderFile);

const oracledb = require("oracledb");
oracledb.initOracleClient();

const dbconfig = require("./dbconfig");
app.get("/", (req, res)=>{
    res.render("index.html");
});

app.get("/select", (req, res)=>{
    getSelection(req, res);
});

app.get("/selectById", (req, res)=>{
    getSelectById(req, res);
})

app.get("/insert", (req, res)=>{
    getInsert(req, res);
})

async function getInsert(req, res){

    oracledb.autoCommit = true;

    let connection;
    try {
        // connection 정보 주입
        connection = oracledb.getConnection({
            user: dbconfig.user,
            password: dbconfig.password,
            connectString: dbconfig.xid
        });
    
        // 쿼리문 실행 / 콜백함수로 결과 데이터 처리
        const result = (await connection).execute(
            "insert into dept values (:deptno, :dname, :loc)",
            // "update dept set dname=:dname, loc=:loc where deptno=:deptno",
            // "delete from dept where deptno =:deptno",
            [99, "개발", "제주"],
            function(error, result){
                console.log("sql 결과처리 콜백함수 실행됨");
                if(error){
                    console.log("error", error);
                    res.send("중복된 부서입니다.");
                }
                console.log(result, result.rowsAffected);
                if(result.rowsAffected==1){
                    res.send("추가완료");
                }
            }
        );
        console.log("result", result);

        // 응답 데이터 전달
        res.send("실행완료");
    } catch (error) {
        console.log(error);
    } finally {
        //커넥션 닫기
        if(connection){
            try {
                (await connection).close;
            } catch (error) {
                console.log("error", error);
            }
            
        }
    }
}

async function getSelectById(req, res){
    let connection;
    try {
        connection = oracledb.getConnection({
            user: dbconfig.user,
            password: dbconfig.password,
            connectString: dbconfig.xid
        });

        const result = (await connection)
            .execute("select * from dept where deptno = :deptno order by deptno", [10]);

        
        res.send((await result).rows);
    } catch (error) {
        
    }
}

// oracledb에 연결하여 select * from dept 의 결과값을 받아 출력하는 함수
async function getSelection(req, res){
    let connection;
    try {
        connection = oracledb.getConnection({
            user: dbconfig.user,
            password: dbconfig.password,
            connectString: dbconfig.xid
        });

        const result = (await connection)
            .execute("select * from dept order by deptno", (error, result)=>{
                if(error){
                    console.log("error: ", error);
                    req.send(error);
                }
                let columns = result.metaData;
                let rowsData =  result.rows;
                let htmlString = "<table border=1><tr>"
                for(let i=0;i<columns.length;i++){
                    htmlString+="<th>"+columns[i].name+"</th>";
                }
                htmlString += "</tr>"
                for(let i=0; i<rowsData.length; i++){
                    htmlString += "<tr>";
                    for(let j=0; j<rowsData[i].length; j++){
                        if(j==0){
                            htmlString+= "<td><a href='/selectOne?deptno="+rowsData[i][j]+"'>"+rowsData[i][j] + "</a></td>";
                        } else{
                            htmlString+= "<td>"+rowsData[i][j] + "</td>";
                        }
                    }
                    htmlString += "</tr>";
                }
                htmlString +="</table>"
                res.send(htmlString);
            });


        // 콜백 밖에서 구현.
        // let data = (await result);
        // // console.log(data);
        // // 목적 : 누적해서 html 응답
        // let htmlString = "<table border=1>"
        // for(let i=0; i<data.length; i++){
        //     htmlString += "<tr>";
        //     for(let j=0; j<data[i].length; j++){
        //         htmlString+= "<td>"+data[i][j] + "</td>";
        //     }
        //     htmlString += "</tr>";
        // }
        // htmlString +="</table>"
        // res.send(htmlString);





        //res.send((await result).rows);

    } catch (error) {
        
    }
}

profile
코딩 프로?

0개의 댓글