메소드 추가 코드
몽고DB도 데이터베이스이므로 인덱스와 속성을 만드는 것이 가능하다. 몽구스에서는 스키마 객체에 메소드를 추가하는 것이 가능한데 바로 static과 method를 이용하는 것이다.
static은 모델 객채에서 사용할 수 있는 함수를 등록하고
method는 모델 인스턴스 객체에서 사용할 수 있는 함수를 등록한다.
UserSchema = mongoose.Schema({
id: {type : String, required : true, unique : true},
password: {type : String, required : true},
name: {type : String, index:'hashed'},
age: {type : Number, 'default' : -1},
created_at: {type : Date, index : {unique : false}, 'default' : Date.now},
updated_at: {type : Date, index : {unique : false}, 'default' : Date.now}
});
UserSchema.static('findById', function(id, callback){
return this.find({id : id}, callback);
});
UserSchema.static('findAll', function(callback){
return this.find({}, callback);
})
console.log('UserSchema 정의함.');
UserModel = mongoose.model("users2", UserSchema);
console.log('UserModel 정의함.');
위의 코드는 이전 코드와 다른 Schema로 잘 보면 user2라고 지정한 것을 볼 수 있다. 보면 기존에 있던 속성에 unique 혹은 required와 같은 특성들을 추가 시켜주었고, Schema에 age, created_at, updated_at 속성을 추가 시키고 static을 통해서 findById 함수와 findAll 함수를 추가하였다.
이제 이 활용을 보자.
var authUser = function(database, id, password, callback){
console.log('authUser 호출됨.');
UserModel.findById(id, function(err, results){
if(err){
callback(err, null);
return;
}
console.log('아이디 [%s]로 사용자 검색 결과', id);
console.dir(results);
if(results.length > 0){
console.log('아이디와 일치하는 사용자 찾음.');
if(results[0]._doc.password === password){
console.log('비밀번호 일치함');
callback(null, results);
} else {
console.log('비밀번호 일치하지 않음');
callback(null,null);
}
}
else{
console.log("아이디와 일치하는 사용자를 찾지 못함");
callback(null, null);
}
});
}
authUser를 다시 손봐주었다. 이번에는 아이디와 비밀번호를 한 번 에 매칭 시키는 것이 아니라 아이디 먼저 그리고 비밀번호를 확인하는 방식으로 바꾸었다.
두 가지가 보이는데 일단 아까 추가 시킨 findById는 우리가 만들어낸 함수로 id가 동일한 데이터를 찾아서 results에 담은 다음 results[0](아이디가 일치하는 것은 하나만 있으면 되니...)의 document를 _doc를 통해서 불러와 password를 매칭시킴으로써 DB에 있는 아이디인지 확인한다.
router.route('/process/listuser').post(function(req,res){
console.log('/process/listuser 호출됨');
if(database){
UserModel.findAll(function(err, results){
if(err){
console.error('사용자 리스트 조회 중 오류 발생 : ' + err.stack);
res.writeHead('200', {'Content-Type' : 'text/html; charset=utf8'});
res.write('<h2>사용자 리스트 조회 중 오류 발생</h2>');
res.write('<p>' + err.stack + '</p>');
res.end();
return ;
}
if(results){
console.dir(results);
res.writeHead('200', {'Content-Type' : 'text/html; charset=utf8'});
res.write('<h2>사용자 리스트</h2>');
res.write('<div><ul>');
for(var i = 0 ; i < results.length ; i++){
var curId = results[i]._doc.id;
var curName = results[i]._doc.name;
res.write(' <li>#' + i + ' : ' + curId + ', ' + curName + '</li>');
}
res.write('</ul></div>');
res.end();
} else {
res.writeHead('200', {'Content-Type' : 'text/html; charset=utf8'});
res.write('<h2>사용자 리스트 조회 실패</h2>');
res.end();
}
});
} else {
res.writeHead('200', {'Content-Type' : 'text/html; charset=utf8'});
res.write('<h2>데이터 베이스 연결 실패</h2>');
res.end();
}
});
그 다음으로 Router.route를 통해서 새로 라우팅을 하였다. 이번에는 전체 조회를 위해서 만든 findAll을 활용하여 user들의 list를 전체 조회한다. findAll은 findById와 다르게 아무조건 없는 탐색이기 때문에 모든 사용자를 조회하는 함수로써 활용한다.
results에는 전체 사용자의 정보가 들어가고 for문을 통해서 _doc를 전체 순회하면서 아이디와 이름을 꺼내서 respone하도록 하였다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>사용자 리스트 테스트</title>
</head>
<body>
<h1>사용자 리스트</h1>
<br>
<form method="post" action="/process/listuser">
<table>
<tr>
<td><label>아래 [전송] 버튼을 누르세요.</label></td>
</tr>
</table>
<input type="submit" value="전송" name="">
</form>
</body>
</html>
마지막으로 아주 간단하게 만든 HTML이다. 이건 잠깐 거쳐가는 HTML이라서 간단하게 만들었다.
코드에 대한 결과
Robo 3T라고 해서 sqldeveloper와 같이 DB의 내부를 볼 수 있는 프로그램이다. 지금 데이터의 내부를 보면 월요일, 화요일, 수요일 이렇게 3가지 데이터가 들어가 있다.
리스트에서 전체 순회 코드를 실행하면 이런식으로 표현을 하게 된다.
PS. 이제 어느정도 안정되어서 그런가 오류에 대한 대처가 좀 발빠르게 변한 것 같다.