본문 바로가기

Node.js

[Node.js 8-1강] mysql DB 연결하고 sql 결과 받아서 활용하는 방법

이번엔 node.js에 데이터베이스를 연결해서 활용하는 방법을 알아보도록 하겠습니다. 

데이터베이스는 mysql을 사용했습니다. 

 

mysql 모듈 설치

명령프롬프트 창에서 mysql 모듈을 설치합니다. 

npm install mysql --save

 

 

DB 접속정보 설정

DB 접속정보는 별도의 파일로 작성해서 필요한 js 파일에서 import해서 사용하도록 구성했습니다. 

 

db_info.js

로컬 DB와 운영 DB 정보가 다른 경우가 많으므로 별도로 구분해서 명시하고, hostname을 이용해서 각 서버환경에 맞는 접속정보를 리턴하도록 설정합니다. 

var  mysql = require('mysql');
var os = require('os');  //호스트 이름을 가져오기 위한 모듈

var dbconnInfo = {
	dev:{
		host: 'localhost',
		port: '3306',
		user: 'test',
		password: 'test',
		database: 'testDB', 
		multipleStatements : true
	},
	real:{
		host     : '1.1.1.1',
		port: '1111',
		user     : 'cafe24',
		password : 'cafe24',
		database : 'cafe24DB',
		multipleStatements : true
	}	
};

var dbconnection = {
	init : function(){
		var hostname = os.hostname();
		if(hostname === 'S1621N14'){
			return mysql.createConnection(dbconnInfo.dev);	//로컬개발환경
		}else{
			return mysql.createConnection(dbconnInfo.real);	//cafe24 서버환경
		}
	},
	
	dbopen : function(con){
		con.connect(function(err){
			if(err){
				console.error("mysql connection error : " + err);
			}else{
				console.info("mysql connection successfully.");
			}
		});
	}
};


module.exports = dbconnection;

 

dbconnection을 호출하는 라우팅 js 파일

clubList.js

require를 통해 db_info.js를 import하고 dbconn을 이용해서 sql을 실행한 결과를 받아옵니다. sql 실행결과는 콜백함수인 results(배열 + json 형태)에 저장되고, 이를 바로 res.render() 함수에 세팅해서 전송하면 됩니다.

var dbConObj = require('../../conf/db_info');	//사용자 정의한 함수 사용
var dbconn = dbConObj.init();

var clubList = {
	//클럽목록
	list : function(req, res){
		
		var sql = 'SELECT * FROM CLUB'; // 클럽목록
		
		dbconn.query(sql, function(err, results, field){
			
			res.render('club/clubList', {data : 'testData list ejs', clubList : results});
		});
	}
};

module.exports = clubList;

 

 

sql 실행결과를 사용하는 ejs 파일

ejs의 if문과 for 문,  <%= %> 를 이용해서 데이터를 표현합니다. 

<!DOCTYPE html>
<html lang="ko">
   <head>
   <% include ../layout/head %>
   </head>

<body>
<% include ../layout/header %>

	<p>js data : <%=data%></p>
	
	<section id="mberClubListSection">
		<h3>가입한 클럽</h3>
		<!-- List 형태는 의미에 맞게 <ul><li>태그 이용 -->
		<% if(clubList != null && clubList.length > 0){ %>
		<ul class="band-club-list">
			<% for ( var i = 0; i < clubList.length; i++){ %>
				<!-- href를 이용해서 페이지 이동시  data-ajax="false" 를 추가해줘야 함. 그렇지 않으면 ajax형태로 가져온 데이터(화면)을 추가함.-->
				<li><a href="/club/detail/<%=clubList[i].CLUB_SN%>"  data-ajax="false" data-bandkey="<%=clubList[i].BAND_KEY%>">
					<img src="<%=clubList[i].COVER_IMAGE%>" alt="<%=clubList[i].CLUB_NM%> 밴드 커버 이미지"><div><%=clubList[i].CLUB_NM%></div>
					<small><%=clubList[i].CLUB_AREA%></small></a>
				</li>
			<% } %>
		</ul>
		<% }else{ %>
		<p>가입한 클럽이 없습니다. 아래에 표시된 네이버밴드 중 하나를 선택해주세요.</p>
		<% } %>
	</section>
	
<% include ../layout/footer %>
</body>
</html>

 

 

mysql query() 함수 좀 더 자세히..

앞에서는 간단한 정보만 알아봤고 query 함수에 대해서 좀 더 알아보도록 하겠습니다. 

 

기본구조

dbconn.query(sql, function(err, results, field){

});

 

select sql 실행시

첫번째 인자인 sql은 1개의 sql 만 전송하거나, 한번에 여러개의 sql을 전송해서 결과값을 받을 수도 있습니다. 

다중 SQL은 다음 강좌를 참고해주세요.

2019/04/02 - [Node.js] - [Node.js] 다중쿼리 처리 방법, sql에 파라미터 매핑하는 다양한 방법

 

그리고 콜백함수의 results는 select sql에 대한 결과값을 가져올 때는 배열[객체]형태로 값을 가져옵니다. 

그래서 results에 대한 결과값을 console로 찎어보려고 할 경우 아래와 같이 사용합니다. 

for (var i = 0; i < results.length; i++) {
  for ( var keyNm in results[i]) {
  	console.log("key : " + keyNm + ", value : " + results[i][keyNm]);
  }
}

 

field 인자는 아래와 같이 SQL 실행 결과 필드값에 대한 정보를 리턴합니다. 활용할 일이 거의 없으므로 field 인자는 생략해도 됩니다. 

[ FieldPacket {
    catalog: 'def',
    db: 'tenniscore',
    table: 'CLUB',
    orgTable: 'club',
    name: 'CLUB_NM',
    orgName: 'CLUB_NM',
    charsetNr: 33,
    length: 150,
    type: 253,
    flags: 4097,
    decimals: 0,
    default: undefined,
    zeroFill: false,
    protocol41: true } ]

 

 

INSERT SQL 실행시

select와 달리 insert sql을 실행할 경우는 신경써서 처리해야할 로직이 좀 더 추가됩니다. 

(정상적으로 insert 가 되었는지, 그리고 insert한 키값을 다시 활용하는 경우 로직 등 )

 

insert 가 정상적으로 적용되었는지 판단하는 방법은 result.affectedRows를 활용합니다. (update, delete도 동일)

insert sql 처리 결과 result는 배열형태가 아니라 객체형태이므로 바로 result.affectedRows를 사용합니다.

if(result.affectedRows > 0){
  //정상 처리됨
  
 }else{
 	//에러 처리
 }

 

 

그리고 insert할 때 생성된 PK 값은 result.insertId를 이용해서 가져올 수 있습니다. 예를 들어 클럽을 생성하고, 바로 생성된 클럽의 상세화면으로 이동해야 할 경우, 또는 클럽을 생성하고 바로 클럽 PK 정보를 다른 테이블의 FK로 사용해서 저장해야 하는 경우 등이죠. 

dbconn.query(insertQuery, paramObj, function(err, result){
  var clubSn = result.insertId;
  res.redirect("/club/" + clubSn);
});

 

 

혹시 디버깅을 위해 실제 수행된 SQL을 보고 싶은 경우

var execSql = dbconn.query(sql, function(err, results){
	...
});

console.log(execSql.sql); //실제 수행된 SQL 확인

query 함수 결과를 변수로 받은 후에 해당 변수의 sql 값을 확인하면 됩니다. 

sql 이외에 다양한 값이 존재하는데 sql 이외에는 딱히 사용할 일이 없었습니다. 

 

 

이상으로 node.js에서 DB(mysql)을 연결하는 방법과 실제 sql 실행결과를 받아서 ejs에서 활용하는 방법을 알아봤습니다. 그런데 실전에서 사용하긴 많이 부족하네요. 다음강좌에서 좀 더 다양한 활용방법을 알아보겠습니다.

 

다음강좌

2019/04/02 - [Node.js] - [Node.js 8-2강] 다중쿼리 처리 방법, sql에 파라미터 매핑하는 다양한 방법