국비 91일차

JAY·2023년 2월 2일
1

국비 공부

목록 보기
83/86

node.js MySQL / MyBatis로 연동

web.js에
const notice = require('./api/notice')
app.use('/notice', notice)
해놓은 상태!!

api

// api/notice.js

const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');

router.use(bodyParser.urlencoded({ extended: true }))

router.get('/', (req, res, next) => {
  

bodyParser.urlencoded를 사용해야 주소창 요청을 읽어들일 수 있다

    var type = req.query.type; // type으로 이름 지어줌
  
    if (type == 'list') {
      // notice?type=list 가 주소창에 찍혔을 때,
        try {
            const dbcon = require('../db/dbconnect');

          // reactSQL.xml과 매치될 값 => dbconnect.js에서 가져올 값
            req.body.mapper = 'reactSQL'; // => xml 파일명, mapper의 namespace 값
            req.body.crud = 'select'; // select 태그 => read
            req.body.mapperid = 'jayContact'; // xml 내 select 태그 id 값

            router.use('/', dbcon);
            next('route');
        }

xml에서 crud 태그는 <insert /> <select /> <update /> <delete />이렇게 되어있다

next('route')는 라우터에서만 동작하는 특수 기능으로
라우터에 연결된 나머지 미들웨어를 건너뛰는데 사용되며 주소와 일치하는 다음 라우터로 이동한다

여기서는 ../db/dbconnect.js 이다

        catch (error) {
            console.log("디비연결에 오류")
        }
    }
    else if (type == 'write') {
        res.send('sql접속할때 update로 해야되것네')
    }
    else if (type == 'update') {
        res.send('sql접속할때 update로 해야되것네')
    }
    else {
        res.send('sql접속할때 delete로 해야되것네')
    }
})


module.exports = router;

dbconnect.js

// dbconnect.js
const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser');
const router = express.Router();
const dbconfig = require('../db/dbconfig');

var mybatisMapper = require('mybatis-mapper');

mybatisMapper.createMapper(['./mapper/reactSQL.xml']) // mapper 파일 연동
var format = { language: 'sql', indent: '  ' } // 언어와 들여쓰기 설정


router.use(bodyParser.json()); // 주소창에서 읽어들인 요청(req) 값을 json으로 파싱


const conn = mysql.createPool(dbconfig) // DB 연결 작업이 들어간다

.createPool()

  • 서버 접속을 매 요청마다 일일이 접속하게 되면 자원낭비가 발생한다
    그래서 풀장처럼 담아서 실행하기 위해 createConnection가 아닌 createPool로 했다

createConnection으로 하게 되면
1. MySQL 모듈을 불러오기
2. DB와 연결하기
3. 쿼리 실행하기
4. 연결 끊기

를 매번 반복해야만 하므로 createPool!


dbconfig.js

  • db접속 정보를 createPool로 실행하므로 dbconfig.js 에 2가지 옵션을 추가한다
    waitForConnections :true, connectionLimit : 5
    접속을 5개씩으로 제한 / 커넥션 대기를 허용해놓았기 때문에
    사용자가 6번째인 사람은 대기 => 하나가 끝나면 접속되도록 처리


(하단) notice.js의 next('route')를 통해 넘어와 실행될 라우터

** router start **
  
router.get('/', (req, res) => {

  var params = req.body; // json 파싱된 요청자료들 params에 저장
  console.log('req.body.body 요청데이터타입 : ', typeof params); //object
  console.log('req.body.body 요청데이터  : ', params); //object

 
  var noticeQuery = mybatisMapper.getStatement(
  
    params.mapper, //이전 라우터(notice.js)에서 추가한 정보 1
    params.mapperid, // 정보 2
    params, // ✨ req.body
    format  // sql 언어이며 들여쓰기 설정됨
  
  ); // xml에서 설정한 값 가져와서 쿼리문 생성
  

params : 리액트에서 요청된 값이 들어감 => xml에서의 #{ } 파라미터 값

.getStatement(
1. xml의 name값 ,
2. 해당 xml의 id값 ,
3. 조회할 파라미터 ,
4. 포맷값
)
순서를 꼭 지켜야 한다고 한다!!

xml 작성

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="reactSQL">
    <select id="jayContact">
        SELECT * FROM jay_contact
        <if test="id!=null and id!=''">
            WHERE ct_id = #{id}
        </if>
        order by ct_id desc
    </select>
</mapper>

MybatisMapper에 .createMapper() 해놓은 파일이다
그리고 .getStatement()를 통해 각종 설정, 연결이 완료되어 xml 안에 작성한 쿼리문이 생성되고


하단의 query를 통해 작성한 것이 실행될 것이다
( noticeQuery가 MybatisMapper.getStatement()이다 )

conn.getConnection((err, connection) => {
  if (err) throw console.log("dB정보 오류  : " + err);

  connection.query(noticeQuery, (error, result) => {
    //DB sql쿼리실행
    if (error) throw "sql문 오류" + error + result; // result를 받지 못하는 상황

      if (params.crud === 'select') {
        // xml 태그에 select가 있을 경우

        res.send(result);
        // select 태그 내 sql문 실행을 통한 결과를 react에게 보내라
        // react에서는 res.data로 접근 가능
        console.log('타입 : ', typeof result, ' 전송데이터 : ', result)

      } else {
        // params.crud가 select를 제외한 나머지 crud(c, u, d)인 경우
        console.log("crud : select외 실행", params.crud)
        res.send("succ"); // react한테 succ라는 문자를 보내기
      }

  })
  connection.release(); // connection.query의 연결 끝내기
  // 다음 서버 접속자 (5번째 안에 못 든 접속자) 대기에서 접속할 수 있도록󠀠
󠀠 })

})

** router end **


module.exports = router;

끝~~!!

0개의 댓글