반응형

안녕하세요.

Spring으로 Web Application을 개발해 보신 분들은 SQL문을 xml로 관리하는 mapper 방식 개발을 해보셨을 겁니다.

MyBatis 라이브러리에서 지원하는 mapper-xml 형식으로 많이들 하셨을 건데요.

 

Node에서도 Spring과 동일하게 mybatis-mapper 모듈을 지원하더라구요.

Node.js와 oracledb 모듈을 이용한 오라클 디비 연결하는 방법에 대해 포스팅을 해드렸는데요.

https://meyouus.tistory.com/66

 

Node.js oracledb를 통한 오라클 연결

안녕하세요. Node.js에서 oracledb 라이브러리를 통한 오라클 연결 방법입니다. ▼사전 준비 작업 - Node 설치 https://meyouus.tistory.com/62 참고 - Oracle Instance Client 설치 다운로드 페이지 : https://ww..

meyouus.tistory.com

SQL 조회하는 부분을 mybatis-mapper 모듈을 이용하여 xml-mapper로 변경을 해보겠습니다.

 

▼사전 준비 작업

- Node 설치

https://meyouus.tistory.com/62 참고

 

- Oracle Instance Client 설치

다운로드 페이지 : https://www.oracle.com/database/technologies/instant-client/downloads.html

설치 참고 : https://sora-muck.tistory.com/12

 

- Node 개발 편집기로 Visual Studio Code 설치

다운로드 페이지 : https://code.visualstudio.com/nodejs

설치 참고 : https://meyouus.tistory.com/21

 

- Request / Response 테스트를 위한 Postman 설치
다운로드 페이지 : https://www.getpostman.com/downloads/

사용법 : https://meetup.toast.com/posts/107

 

- DB 데이터 EMP, DEPT 생성

https://meyouus.tistory.com/50 참고

▼ oracledb 모듈(라이브러리) 설치

npm install oracledb --save

▼ express 모듈 설치 모듈(라이브러리) 설치

npm install express --save

▼ body-parser 모듈 설치

npm install body-parser --save

mybatis-mapper 모듈 설치

npm install mybatis-mapper --save

기본설정

// mybatis-mapper 추가

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

 

// Mapper Load

mybatisMapper.createMapper([ './mapper/oracle-mapper.xml' ]);

 

// Oracle Auto Commit 설정

oracledb.autoCommit = true;

var dbConfig = require('./config/dbConfig');
// Express 기본 모듈 불러오기
var express = require('express')
  , http = require('http')
  , path = require('path');

// 익스프레스 객체 생성
var app = express();
 
// 기본 속성 설정
app.set('port', process.env.PORT || 3000);

// body-parser
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());

// 라우터 객체 참조
var router = express.Router();

// mybatis-mapper 추가
var mybatisMapper = require('mybatis-mapper');

// Mapper Load
mybatisMapper.createMapper([ './APP/mapper/oracle-mapper.xml' ]);

// Oracle Auto Commit 설정
oracledb.autoCommit = true;

▼ dbConfig.js 설정

- dbConfig.js : db 연결 정보

/*  DB Info */
module.exports = 
{
    user : process.env.NODE_ORACLEDB_USER || "*****",
    password : process.env.NODE_ORACLEDB_PASSWOR || "********",
    connectString : process.env.NODE_ORACLEDB_CONNECTIONSTRING || "localhost/orcl"
}

▼ xml-mapper 파일 설정

- oracle-mapper.xml 생성

▷ 조회(SELECT) - 사번(empno) 정보가 있는경우 해당하는 사번의 정보, Null인경우 전체 사원정보 조회

  <select id="selectEmpInfo">
    SELECT
      *
    FROM
      EMP 
    WHERE EMPNO IS NOT NULL
    <if test="empno != null and empno != ''" >
      AND EMPNO = #{empno}
    </if>
  </select>

▷ 등록(INSERT) - 사원정보 저장

  <insert id="insertEmpInfo">
    INSERT INTO EMP( EMPNO ,ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
    VALUES( #{empno} ,#{ename}, #{job}, #{mgr}, SYSDATE, #{sal}, #{comm}, #{deptno} )
  </insert> 

▷ 전체

<?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="oracleMapper">  
  <select id="selectEmpInfo">
    SELECT
      *
    FROM
      EMP 
    WHERE EMPNO IS NOT NULL
    <if test="empno != null and empno != ''" >
      AND EMPNO = #{empno}
    </if>
  </select>

  <insert id="insertEmpInfo">
    INSERT INTO EMP( EMPNO ,ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
    VALUES( #{empno} ,#{ename}, #{job}, #{mgr}, SYSDATE, #{sal}, #{comm}, #{deptno} )
  </insert>  
</mapper>

▼ Application 파일 설정

- app.js : Oracle 연결, CURD 처리, Request / Response 처리

 

▷ 조회 Request 처리 : /dbTestSelect

// 데이터 조회 처리
router.post('/dbTestSelect', function(request, response){

    oracledb.getConnection({
        user            : dbConfig.user,
        password        : dbConfig.password,
        connectString   : dbConfig.connectString
    },
    function(err, connection) {
        if (err) {
            console.error(err.message);
            return;
        }

        //조회할 파라미터
        var param = {
            empno : request.body.empno
        }

        // 쿼리문 형식
        let format = {language: 'sql', indent: '  '};
        //첫번째는 xml의 namespace, 두번째는 해당 xml id값, 세번째는 파라미터, 마지막은 포맷.
        let query = mybatisMapper.getStatement('oracleMapper', 'selectEmpInfo', param, format);
        console.log(query);  // 쿼리 출력

        connection.execute(query, [], function (err, result) {
            if (err) {
                console.error(err.message);
                doRelease(connection);
                return;
            }
            console.log(result.rows);                   // 데이터
            doRelease(response, connection, result.rows);         // Connection 해제
        });
    });    
});

 

▷ 등록 Request 처리 : /dbTestInsert

// 데이터 입력 처리
router.post('/dbTestInsert', function(request, response){

    oracledb.getConnection({
        user            : dbConfig.user,
        password        : dbConfig.password,
        connectString   : dbConfig.connectString
    },
    function(err, connection) {
        if (err) {
            console.error(err.message);
            return;
        }

        //조회할 파라미터
        var param = {
            empno : Number(request.body.empno),
            ename : request.body.ename,
            job : request.body.job,
            mgr : request.body.mgr,
            sal : Number(request.body.sal),
            comm : Number(request.body.comm),
            deptno : Number(request.body.deptno)   
        }

        // 쿼리문 형식
        let format = {language: 'sql', indent: '  '};
        //첫번째는 xml의 namespace, 두번째는 해당 xml id값, 세번째는 파라미터, 마지막은 포맷.
        let query = mybatisMapper.getStatement('oracleMapper', 'insertEmpInfo', param, format);

        console.log(query);  // 쿼리 출력

        connection.execute(query, [], function (err, result) {
            if (err) {
                console.error(err.message);
                doRelease(connection);
                return;
            }
            console.log('Row Insert: ' + result.rowsAffected);
        doRelease(response, connection, result.rowsAffected);         // Connection 해제
        });
    });
});

▼ app.js

var oracledb = require('oracledb');
var dbConfig = require('./config/dbConfig');
// Express 기본 모듈 불러오기
var express = require('express')
  , http = require('http')
  , path = require('path');

// 익스프레스 객체 생성
var app = express();
 
// 기본 속성 설정
app.set('port', process.env.PORT || 3000);

// body-parser
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());

// 라우터 객체 참조
var router = express.Router();

// mybatis-mapper 추가
var mybatisMapper = require('mybatis-mapper');

// Mapper Load
mybatisMapper.createMapper([ './mapper/oracle-mapper.xml' ]);

// Oracle Auto Commit 설정
oracledb.autoCommit = true;

// 데이터 조회 처리
router.post('/dbTestSelect', function(request, response){

    oracledb.getConnection({
        user            : dbConfig.user,
        password        : dbConfig.password,
        connectString   : dbConfig.connectString
    },
    function(err, connection) {
        if (err) {
            console.error(err.message);
            return;
        }

        //조회할 파라미터
        var param = {
            empno : request.body.empno
        }

        // 쿼리문 형식
        let format = {language: 'sql', indent: '  '};
        //첫번째는 xml의 namespace, 두번째는 해당 xml id값, 세번째는 파라미터, 마지막은 포맷.
        let query = mybatisMapper.getStatement('oracleMapper', 'selectEmpInfo', param, format);

        console.log(query);  // 쿼리 출력

        connection.execute(query, [], function (err, result) {
            if (err) {
                console.error(err.message);
                doRelease(connection);
                return;
            }
            console.log(result.rows);                   // 데이터
            doRelease(response, connection, result.rows);         // Connection 해제
        });
    });
});


// 데이터 입력 처리
router.post('/dbTestInsert', function(request, response){

    oracledb.getConnection({
        user            : dbConfig.user,
        password        : dbConfig.password,
        connectString   : dbConfig.connectString
    },
    function(err, connection) {
        if (err) {
            console.error(err.message);
            return;
        }

        //조회할 파라미터
        var param = {
            empno : Number(request.body.empno),
            ename : request.body.ename,
            job : request.body.job,
            mgr : request.body.mgr,
            sal : Number(request.body.sal),
            comm : Number(request.body.comm),
            deptno : Number(request.body.deptno)   
        }

        // 쿼리문 형식
        let format = {language: 'sql', indent: '  '};
        //첫번째는 xml의 namespace, 두번째는 해당 xml id값, 세번째는 파라미터, 마지막은 포맷.
        let query = mybatisMapper.getStatement('oracleMapper', 'insertEmpInfo', param, format);

        console.log(query);  // 쿼리 출력

        connection.execute(query, [], function (err, result) {
            if (err) {
                console.error(err.message);
                doRelease(connection);
                return;
            }
            console.log('Row Insert: ' + result.rowsAffected);
        doRelease(response, connection, result.rowsAffected);         // Connection 해제
        });
    });    

});


// DB 연결 해제
function doRelease(response, connection, result) {
    connection.release(function (err) {
        if (err) {
            console.error(err.message);
        }

        // DB종료까지 모두 완료되었을 시 응답 데이터 반환
        response.send(''+result);
    });
}

// 라우터 객체를 app 객체에 등록
app.use('/', router);
 
 
// 등록되지 않은 패스에 대해 페이지 오류 응답
app.all('*', function(req, res) {
    res.status(404).send('<h1>ERROR - 페이지를 찾을 수 없습니다.</h1>');
});
 
 
// Express 서버 시작
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

// 예상치 못한 에러처리
process.on("uncaughtException", function (err) {
    //비정상 에러시 로그를 넘길 수 있도록 timeout을 준다. 
    setTimeout(function () {
        logger.error("[[[ Uncaught Exception ]]]\n" + err.stack);
    }, 1000);
});

▼ launch.json  <-- Visual Studio Run and Debug Mode 설정

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [

        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program": "${workspaceFolder}\\app.js",
            "outputCapture": "std"
        }
    ]
}

 

▼ Test

1. 조회 : http://localhost:3000/dbTestSelect

API : http://localhost:3000/dbTestSelect

1-1. empno 지정 -> 해당 사원정보가 있는경우 1건 Response

- Log


1-2. empno 지정안함 -> 전체 사원정보 Response

- Log


2. 사원정보 저장

API : http://localhost:3000/dbTestInsert

- Log

 

Nodejs Mybatis Sample.zip
0.01MB


이상으로 mybatis-mapper 모듈을 이용한 mapper-xml 개발에 대해 설명을 드렸습니다.

업무에 도움이 되셨으면 합니다.

 

감사합니다.

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기