// view 엔진으로 보여줄 파일들의 경로 설정
app.set("views", path.join(__dirname, "page"));
// view 엔진으로 ejs를 사용하도록 설정
app.set("view engine", "ejs");
// page 폴더 안의 ejs 파일들을 보여줄 것이다.
4. body객체와 정적인 파일을 사용하기 위한 미들웨어 추가
// body 객체 사용하기 위해 미들웨어 추가
// 깊은 객체를 사용할 건가? 'extended : false == 사용안함'. 사용할 일이 없다.
app.use(express.urlencoded({extended : false}));
// 정적인 파일을 사용하기 위해 미들웨어 추가
// 정적인 파일을 모아놓은 경로를 public 폴더로 지정
app.use(express.static(path.join(__dirname,"public")));
// 이렇게 지정한 경우에는 ejs단에 '/css/파일명'으로 접근을 하면 된다.
// 정적 파일 경로도 나눌 수 있다.
app.use("/css",express.static(path.join(__dirname,"public")))
5. 루트경로의 변경
' /posts/ ~ ' 이 뒷 부분의 경로로 입력해야 ' routes - posts.js ' 의 경로로 이동할 수 있다.
이렇게 해야 routes - posts.js의 로직들을 사용할 수 있어요.....아마도....?
// postRoute객체에 get 메서드로 / 루트경로 지정했을 때
// "/posts"이 경로도 추가되어 라우팅된다.
// 게시글은 /posts 붙여야 루트경로로 요청이 된다.
app.use("/posts", postRoute);
6. 포트를 생성하고 서버를 대기상태로 만들어준다.
// 서버가 열릴 포트번호 지정
const PORT = 8000;
// 서버 대기
app.listen(PORT,()=>{
console.log("서버 잘 열림")
})
models
데이터와 비즈니스 로직을 관리할 'models' 폴더 생성
1. config.js - Mysql에 연결하는 작업 진행
먼저 mysql에 연결을 진행해, 데이터베이스에 저장을 할 수 있도록 준비한다.
1. 외부모듈 'Mysql2' 선언
// createPool을 사용하기 위해 promise api 선언하여 사용
// createPool를 생성하고 관리할 수 있는 메소드이다.
const mysql2 = require("mysql2/promise");
2. createPool 메소드로 Mysql 연결
createConnection
우리가 이전에 사용했던 방식
콜백 함수 기반이며, promise를 반환하지 않았다.
기본적인 연결을 해주는 메소드이며 테스트할 때 사용한다.
단일 클라이언트 접속에 용이하다.
createPool
promise 객체를 반환한다.
많은 클라이언트가 데이터베이스와 통신할 때, 요청이 많이 들어와도 성능이 유지되고 여러 개의 요청을 처리하는데 좋다.
async, await의 원활한 동작이 가능하다.
const mysql = mysql2.createPool({
user : "root",
password : "000000",
// 다중 쿼리문 사용할 예정
// 다중 쿼리문 설정 - 다른 쿼리문을 실행해서 글 번호를 다시 순서대로 적용하도록함
multipleStatements : true,
database : "test1"
})
multipleStatements
해당 쿼리문에 true 값을 주면, 세미콜론(;)으로 이어진 여러개의 쿼리문을 한꺼번에 적용시킬 수 있다.
3. getConnection 연결 확인 메서드 선언
getConnection: 자바 프로그램과 데이터베이스를 네트워크상에서 연결해주는 메소드이다.
//연결 확인 메서드
mysql.getConnection((err,res)=>{
// 연결이 정상적으로 되지 않으면
console.log(err);
// 정상적으로 연결되면 res객체에 연결 인스턴스가 넘어온다.
})
4. 외부파일에 mysql의 내용을 내보낸다.
// 외부파일에서 mysql의 내용을 받을 수 있도록 내보낸다.
module.exports = mysql;
2. posts.js - 게시판의 기능들을 작업
1. config.js의 mysql객체가 담고있는 데이터베이스를 가져온다.
const mysql = require("./config")
2. 테이블을 초기화 해주는 함수를 선언
게시판의 기능들이 담길 객체 posts 선언
const posts = {
// 테이블을 초기화 해주는 함수
initTable : async function(){ ... },
// 글의 리스트를 조회하는 함수
viewPostAll : async function(){ ... },
// 글을 선택했을 때 글 하나를 보여줄 함수
selectPost : async function(id){ ... },
// 글을 추가 해주는 메서드
insert : async function(title, content){ ... },
// 글 수정하는 메서드
update : async function(id, title, content){ ... },
// 글을 삭제하는 메소드
delete : async function(id){ ... }
};
async function
비동기 함수이다.
promise 코드를 보다 직관적으로 나타낼 수 있다.
// 테이블을 초기화 해주는 함수
initTable : async function(){
try {
// 배열의 스프레드 연산자. 0 1 2 3 4 이런 식으로 순서대로 담긴다.
const[result] = await mysql.query("SELECT * FROM posts");
console.log(result)
} catch (error) {
// 테이블이 없어 에러가 나면 posts 테이블을 생성한다.
await mysql.query("CREATE TABLE posts(id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(20), content VARCHAR(100))")
}
}
3. 글의 리스트를 조회하는 함수를 선언
// 글의 리스트를 조회하는 함수
viewPostAll : async function(){
try {
const [result] = await mysql.query('SELECT * FROM posts');
// posts 테이블의 데이터 전부 조회
return result;
} catch (error) {
console.log("글 전체 조회 에러남");
}
}
4. 글을 선택할 때 하나의 글을 보여주는 함수 선언
selectPost : async function(id){
try {
const [result] = await mysql.query("SELECT * FROM posts WHERE id = ?", [id]);
console.log("선택한 게시글 : ",result[0]);
return result[0];
} catch (error) {
console.log("글 선택 조회 에러남")
}
}
5. 글을 추가해주는 함수 선언
// 글을 추가 해주는 메서드
insert : async function(title, content){
try {
await mysql.query("INSERT INTO posts (title, content) VALUES (?,?)",[title, content]);
console.log("글 추가 완료~");
} catch (error) {
console.log("글 추가 에러남!");
}
}
6. 글을 수정하는 함수 선언
// 글 수정하는 메서드
update : async function(id, title, content){
try {
await mysql.query("UPDATE posts SET title = ?, content = ? WHERE id = ?",[title, content, id]);
console.log("게시글 수정 완료!")
} catch (error) {
console.log(error);
}
}
7. 글을 삭제하는 함수 선언
// 글을 삭제하는 메소드
delete : async function(id){
try {
await mysql.query("DELETE FROM posts WHERE id=?; SET @CNT = 0; UPDATE posts SET posts.id = @CNT:=@CNT+1; ALTER TABLE posts AUTO_INCREMENT = 0;",[id]);
console.log("게시글 삭제 완료");
} catch (error) {
console.log("게시글 삭제 에러남!")
}
}
8. 게시판의 기능(2번 ~ 7번)을 담은 객체를 exports를 사용하여 내보낸다.
module.exports = posts;
3. index.js - config.js와 posts.js의 모듈을 받는 js파일
index.js를 생성한 이유는 require로 경로를 지정할 때, 경로의 파일명이 아닌 폴더명 까지만 입력하면 기본적으로 ' index.js '를 찾기 때문이다.