반응형

*사이트 DB연동 작업

1. 사용한 MySQL 코드

- VARCHAR(100)은 용량을 아끼는 모드 / 일반 CHAR(100)은 용량을 아끼기 보단, 속도가 빠른 모드

- LONGTEXT는 긴 본문의 경우 잘리게 하는 것.

DROP DATABASE IF EXISTS blog;
CREATE DATABASE blog;
USE blog;

CREATE TABLE `article` (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    updateDate DATETIME NOT NULL,
    title CHAR(100) NOT NULL,
    `body` LONGTEXT NOT NULL
);

INSERT INTO article
SET regDate = NOW(),
updateDate = NOW(),
title = "aaa",
`body` = "aaa"
반응형
반응형

*MVC 게시판 (DB연동/패키지 분리) 맴버/댓글 기능 작업 중
- 게시물 CRUD(생성/읽기/수정/삭제), 댓글 CRUD
- CRUD란 CREATE(INSERT) / READ(SELECT) /UPDATE /DELETE

*추가 요구사항
member 기능 관련
- 회원가입 기능 구현(완료)
- 아이디 중복 방지(완료)
- 로그인 기능 구현(완료)
- 중복 로그인 방지(완료)
- 현재 로그인중인 대상 확인 가능(완료)
article 기능 관련
- 게시물 상세보기 구현(완료)
- 게시물 작성
- 로그인 한 회원만 작성 가능(완료)
- 게시물 수정
- 작성자만 수정 가능(완료)
- 게시물 삭제
- 작성자만 삭제 가능(완료)
comment 기능 관련( articleReply 테이블이 댓글 )
- 댓글은 상세보기 시 작성.
- 댓글 작성 (완료) - 게시물 CRUD(생성/읽기/수정/삭제), 댓글 CRUD
- CRUD란 CREATE(INSERT) / READ(SELECT) /UPDATE /DELETE
*추가 요구사항
member 기능 관련
- 회원가입 기능 구현(완료)
- 아이디 중복 방지(완료)
- 로그인 기능 구현(완료)
- 중복 로그인 방지(완료)
- 현재 로그인중인 대상 확인 가능(완료)
article 기능 관련
- 게시물 상세보기 구현(완료)
- 게시물 작성
- 로그인 한 회원만 작성 가능(완료)
- 게시물 수정
- 작성자만 수정 가능(완료)
- 게시물 삭제
- 작성자만 삭제 가능(완료)
comment 기능 관련( articleReply 테이블이 댓글 )
- 댓글은 상세보기 시 작성.
- 댓글 작성 (완료)
- 댓글 삭제 (완료)
- 댓글도 article 처럼 삭제
- 댓글 수정 (완료)

*사용한 SQL 코드

CREATE DATABASE site5;
USE site5;

CREATE TABLE `member` (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    loginId CHAR(100) NOT NULL UNIQUE,
    loginPw CHAR(100) NOT NULL,
    `name` CHAR(100) NOT NULL
);

CREATE TABLE `board` (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    `code` CHAR(100) NOT NULL UNIQUE,
    `name` CHAR(100) NOT NULL
);

CREATE TABLE `article` (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    title CHAR(100) NOT NULL,
    `body` CHAR(100) NOT NULL,
    memberId INT(10) UNSIGNED NOT NULL,
    boardId INT(10) UNSIGNED NOT NULL,
    INDEX boardId (`boardId`)
);

CREATE TABLE `articleReply` (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    `body` CHAR(100) NOT NULL,
    memberId INT(10) UNSIGNED NOT NULL,
    articleId INT(10) UNSIGNED NOT NULL,
    INDEX articleId (`articleId`)
);

반응형
반응형

*MVC 영속저장 게시판 작업(DB연동 / 패키지 분리)

1. 사용한 MYSQL 코드

CREATE DATABASE site5;
USE site5;

CREATE TABLE `member` (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    loginId CHAR(100) NOT NULL UNIQUE,
    loginPw CHAR(100) NOT NULL,
    `name` CHAR(100) NOT NULL
);

CREATE TABLE `board` (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    `code` CHAR(100) NOT NULL UNIQUE,
    `name` CHAR(100) NOT NULL
);

CREATE TABLE `article` (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    title CHAR(100) NOT NULL,
    `body` CHAR(100) NOT NULL,
    memberId INT(10) UNSIGNED NOT NULL,
    boardId INT(10) UNSIGNED NOT NULL,
    INDEX boardId (`boardId`)
);

CREATE TABLE `articleReply` (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    `body` CHAR(100) NOT NULL,
    memberId INT(10) UNSIGNED NOT NULL,
    articleId INT(10) UNSIGNED NOT NULL,
    INDEX articleId (`articleId`)
);

 

2. 자바 코드 검토 관련

- 패키지로 분리되어있는 상태에서 시작.
- 초기에 board에 notice / free 게시판 존재( 없는 경우 자동으로 생성(중복생성 방지 존재))
- article / member / build 관련 존재
- article - list / write / changeboard / currentboard 존재 / delete / modify 추가완료
- member - logout / login / whoami / join 존재
- build - site 존재

명령어
- article list : 선택된 게시판의(notice / free) 게시물 리스트를 보여줌
- article write
- article delete 게시물 번호
- article modify 게시물 번호
- article changeBoard 게시판 명(notice/free)
- article currentBoard : 현재 선택된 게시판 정보를 알려줌

반응형
반응형

*요구사항(DB 연동)

- 게시물 추가 / 수정 / 삭제 / 리스팅 / 상세보기 / 게시판 변경 / 빌드 사이트(수동/자동)

 

추가 작업 완료

1. 게시물 추가(완료)

2. 게시물 수정(완료)

- 수정 할 게시물 존재유무 체크

3. 게시물 삭제(완료)

- 삭제 할 게시물 존재유무 체크

4. 게시물 리스팅(완료)

5. 게시물 상세보기(완료)

- 상세보기 할 게시물 존재유무 체크

6. 게시판 선택기능(완료)

- 프로그램 실행 시 게시판 자동 생성(notice, free)프로그램 실행 시 게시판 자동 생성(notice, free) 자동생성 막기 구현했으나 초기에 아무것도 없을 때는 오류 발생

- 아예 초기에 테이블 생성 시 notice / free 생성되도록 진행(수동)

7. 빌드 사이트(완료)

- build siteauto 추가 / build stop으로 종료 가능

8. 개선작업 진행(추가 / 수정 / 삭제 / 리스팅 / 상세보기 개선완료)

9. DB / TABLE 관련 제거

10. html / css 통계 추가

 

*MySQL 코드

- 작업 때 사용한 코드

CREATE DATABASE site5;

USE site5;

CREATE TABLE article (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    title CHAR(100) NOT NULL,
    `body` TEXT NOT NULL,
    boardId INT(10) UNSIGNED NOT NULL
);

CREATE TABLE board (
    id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    `name` CHAR(100) NOT NULL,
    `code` INT(10) UNSIGNED NOT NULL
);

INSERT INTO board SET regDate = NOW(), `name` = 'notice', `code` = '1'
INSERT INTO board SET regDate = NOW(), `name` = 'free', `code` = '2'

SHOW TABLES;

SELECT * FROM article ORDER BY id DESC

 

*이클립스 코드

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

class Main {
	public static void main(String[] args) {
		App app = new App();
		app.start();
	}
}

//MySQL DB 연결
class DBConnection {
	Connection connection;

	// DB 연결
	public void connect() {
		String url = "jdbc:mysql://localhost:3306/site5?serverTimezone=UTC";
		String user = "sbsst";
		String password = "sbs123414";
		String driverName = "com.mysql.cj.jdbc.Driver";

		try {
			// ① 로드(카카오 택시에 `com.mysql.cj.jdbc.Driver` 라는 실제 택시 드라이버를 등록)
			// 하지만 개발자는 실제로 `com.mysql.cj.jdbc.Driver`를 다룰 일은 없다.
			// 내부적으로 JDBC가 알아서 다 해주기 때문에 우리는 JDBC의 DriverManager 를 통해서 DB와의 연결을 얻으면 된다.
			Class.forName(driverName);

			// ② 연결
			connection = (Connection) DriverManager.getConnection(url, user, password);
		} catch (ClassNotFoundException e) {
			// `com.mysql.cj.jdbc.Driver` 라는 클래스가 라이브러리로 추가되지 않았다면 오류발생
			System.out.println("[로드 오류]\n" + e.getStackTrace());
		} catch (SQLException e) {
			// DB접속정보가 틀렸다면 오류발생
			System.out.println("[연결 오류]\n" + e.getStackTrace());
		}
	}

	// DB 연결 종료
	public void close() {
		try {
			if (connection != null) {
				connection.close();
			}
		} catch (SQLException e) {
			System.out.println("[닫기 오류]\n" + e.getStackTrace());
		}
	}

	// 게시물 추가(작성)
	public int insert(String sql) {
		int id = -1;

		// SQL을 적는 문서파일
		Statement statement = null;
		// SQL의 실행결과 보고서
		ResultSet rs = null;

		try {
			statement = connection.createStatement();
			statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
			rs = statement.getGeneratedKeys();
			if (rs.next()) {
				id = rs.getInt(1);
			}
		} catch (SQLException e) {
			System.out.println("[INSERT 쿼리 오류]\n" + e.getStackTrace());
		}

		try {
			if (statement != null) {
				statement.close();
			}

			if (rs != null) {
				rs.close();
			}
		} catch (SQLException e) {
			System.out.println("[INSERT 종료 오류]\n" + e.getStackTrace());
		}

		return id;
	}

	// 게시물 수정
	public int update(String sql) {
		// UPDATE 명령으로 몇개의 데이터가 수정되었는지
		int affectedRows = 0;

		// SQL을 적는 문서파일
		Statement statement = null;

		try {
			statement = connection.createStatement();
			affectedRows = statement.executeUpdate(sql);
		} catch (SQLException e) {
			System.err.printf("[UPDATE 쿼리 오류, %s]\n" + e.getStackTrace() + "\n", sql);
		}

		try {
			if (statement != null) {
				statement.close();
			}
		} catch (SQLException e) {
			System.err.println("[UPDATE 종료 오류]\n" + e.getStackTrace());
		}

		return affectedRows;
	}

	// 게시물 삭제
	public void delete(String sql) {
		// int ret = 0;

		// SQL을 적는 문서파일
		Statement statement = null;

		try {
			statement = connection.createStatement();
			statement.executeUpdate(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}

	}

	// 게시물 리스트(상세보기)
	public Map<String, Object> selectRow(String sql) {
		List<Map<String, Object>> rows = selectRows(sql);

		if (rows.size() > 0) {
			return rows.get(0);
		}

		return new HashMap<>();
	}

	// 게시물 리스트 관련
	public List<Map<String, Object>> selectRows(String sql) {
		// SQL을 적는 문서파일
		Statement statement = null;
		ResultSet rs = null;

		List<Map<String, Object>> rows = new ArrayList<>();

		try {
			statement = connection.createStatement();
			rs = statement.executeQuery(sql);
			// ResultSet 의 MetaData를 가져온다.
			ResultSetMetaData metaData = rs.getMetaData();
			// ResultSet 의 Column의 갯수를 가져온다.
			int columnSize = metaData.getColumnCount();

			// rs의 내용을 돌려준다.
			while (rs.next()) {
				// 내부에서 map을 초기화
				Map<String, Object> row = new HashMap<>();

				for (int columnIndex = 0; columnIndex < columnSize; columnIndex++) {
					String columnName = metaData.getColumnName(columnIndex + 1);
					// map에 값을 입력 map.put(columnName, columnName으로 getString)
					row.put(columnName, rs.getObject(columnName));
				}
				// list에 저장
				rows.add(row);
			}
		} catch (SQLException e) {
			System.err.printf("[SELECT 쿼리 오류, %s]\n" + e.getStackTrace() + "\n", sql);
		}

		try {
			if (statement != null) {
				statement.close();
			}

			if (rs != null) {
				rs.close();
			}
		} catch (SQLException e) {
			System.err.println("[SELECT 종료 오류]\n" + e.getStackTrace());
		}

		return rows;
	}

	// 게시판(Board) 생성
	public int insertBoard(String sql) {
		int id = -1;

		// SQL을 적는 문서파일
		Statement statement = null;
		// SQL의 실행결과 보고서
		ResultSet rs = null;

		try {
			statement = connection.createStatement();
			statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
			rs = statement.getGeneratedKeys();
			if (rs.next()) {
				id = rs.getInt(1);
			}
		} catch (SQLException e) {
			System.out.println("[INSERT 쿼리 오류]\n" + e.getStackTrace());
		}

		try {
			if (statement != null) {
				statement.close();
			}

			if (rs != null) {
				rs.close();
			}
		} catch (SQLException e) {
			System.out.println("[INSERT 종료 오류]\n" + e.getStackTrace());
		}

		return id;
	}

	// int값 반환
	public int selectRowIntValue(String sql) {
		Map<String, Object> row = selectRow(sql);

		for (String key : row.keySet()) {
			Object value = row.get(key);

			if (value instanceof String) {
				return Integer.parseInt((String) value);
			}
			if (value instanceof Long) {
				return (int) (long) value;
			} else {
				return (int) value;
			}
		}

		return -1;
	}

	// String값 반환
	public String selectRowStringValue(String sql) {
		Map<String, Object> row = selectRow(sql);

		for (String key : row.keySet()) {
			Object value = row.get(key);

			return value + "";
		}

		return "";
	}

	// Boolean값 반환
	public boolean selectRowBooleanValue(String sql) {
		int rs = selectRowIntValue(sql);

		return rs == 1;
	}

}

// Session
// 현재 사용자가 이용중인 정보
// 이 안의 정보는 사용자가 프로그램을 사용할 때 동안은 계속 유지된다.
class Session {
	private Board currentBoard;

	public Board getCurrentBoard() {
		return currentBoard;
	}

	public void setCurrentBoard(Board currentBoard) {
		this.currentBoard = currentBoard;
	}
}

// Factory
// 프로그램 전체에서 공유되는 객체 리모콘을 보관하는 클래스
class Factory {
	private static Session session;
	//private static DB db;
	private static BuildService buildService;
	private static ArticleService articleService;
	private static ArticleDao articleDao;
	private static Scanner scanner;
	private static DBConnection dbConnection;

	// DB 연동 관련
	public static DBConnection getDBConnection() {
		if (dbConnection == null) {
			dbConnection = new DBConnection();
		}
		return dbConnection;
	}

	// 세션
	public static Session getSession() {
		if (session == null) {
			session = new Session();
		}

		return session;
	}

	// 스캐너
	public static Scanner getScanner() {
		if (scanner == null) {
			scanner = new Scanner(System.in);
		}

		return scanner;
	}
/* db관련 제거
	public static DB getDB() {
		if (db == null) {
			db = new DB();
		}

		return db;
	}
*/
	public static ArticleService getArticleService() {
		if (articleService == null) {
			articleService = new ArticleService();
		}

		return articleService;
	}

	public static ArticleDao getArticleDao() {
		if (articleDao == null) {
			articleDao = new ArticleDao();
		}

		return articleDao;
	}

	public static BuildService getBuildService() {
		if (buildService == null) {
			buildService = new BuildService();
		}

		return buildService;
	}
}

// App
class App {
	private Map<String, Controller> controllers;

	// 컨트롤러 만들고 한곳에 정리
	// 나중에 컨트롤러 이름으로 쉽게 찾아쓸 수 있게 하려고 Map 사용
	void initControllers() {
		controllers = new HashMap<>();
		controllers.put("build", new BuildController());
		controllers.put("article", new ArticleController());
	}

	public App() {
		// 컨트롤러 등록
		initControllers();

		// DB 연동 (App 실행 시 연동)
		Factory.getDBConnection().connect();

		/*
		// 게시판(Board) 생성
		Factory.getArticleService().makeBoard("notice", "1");
		Factory.getArticleService().makeBoard("free", "2");
		*/

		// 현재 게시판을 1번 게시판으로 선택 해당 보드가 전달됨
		Factory.getSession().setCurrentBoard(Factory.getArticleService().getBoard(1));

	}

	public void start() {

		while (true) {
			System.out.printf("게시판 명령어 : ");
			String command = Factory.getScanner().nextLine().trim();

			if (command.length() == 0) {
				continue;
			} else if (command.equals("exit")) {
				break;
			}

			Request reqeust = new Request(command);

			if (reqeust.isValidRequest() == false) {
				continue;
			}

			if (controllers.containsKey(reqeust.getControllerName()) == false) {
				continue;
			}

			controllers.get(reqeust.getControllerName()).doAction(reqeust);
		}

		// DB 연동 종료
		Factory.getDBConnection().close();

		// 스캐너 종료
		Factory.getScanner().close();
	}
}

// Request
class Request {
	private String requestStr;
	private String controllerName;
	private String actionName;
	private String arg1;
	private String arg2;
	private String arg3;

	boolean isValidRequest() {
		return actionName != null;
	}

	// 명령어 입력 받으면 분할
	Request(String requestStr) {
		this.requestStr = requestStr;
		String[] requestStrBits = requestStr.split(" ");
		this.controllerName = requestStrBits[0];

		if (requestStrBits.length > 1) {
			this.actionName = requestStrBits[1];
		}

		if (requestStrBits.length > 2) {
			this.arg1 = requestStrBits[2];
		}

		if (requestStrBits.length > 3) {
			this.arg2 = requestStrBits[3];
		}

		if (requestStrBits.length > 4) {
			this.arg3 = requestStrBits[4];
		}
	}

	public String getControllerName() {
		return controllerName;
	}

	public void setControllerName(String controllerName) {
		this.controllerName = controllerName;
	}

	public String getActionName() {
		return actionName;
	}

	public void setActionName(String actionName) {
		this.actionName = actionName;
	}

	public String getArg1() {
		return arg1;
	}

	public void setArg1(String arg1) {
		this.arg1 = arg1;
	}

	public String getArg2() {
		return arg2;
	}

	public void setArg2(String arg2) {
		this.arg2 = arg2;
	}

	public String getArg3() {
		return arg3;
	}

	public void setArg3(String arg3) {
		this.arg3 = arg3;
	}
}

// Controller
abstract class Controller {
	abstract void doAction(Request reqeust);
}

// ArticleController
class ArticleController extends Controller {
	private ArticleService articleService;

	ArticleController() {
		articleService = Factory.getArticleService();
	}

	public void doAction(Request reqeust) {
		if (reqeust.getActionName().equals("write")) {
			actionWrite(reqeust);
		} else if (reqeust.getActionName().equals("modify")) {
			actionModify(reqeust);
		} else if (reqeust.getActionName().equals("delete")) {
			actionDelete(reqeust);
		} else if (reqeust.getActionName().equals("list")) {
			actionList(reqeust);
		} else if (reqeust.getActionName().equals("detail")) {
			actionDetail(reqeust);
		} else if (reqeust.getActionName().equals("changeboard")) {
			actionChangBoard(reqeust);
		}
	}

	// 게시물 추가(작성)(DB연동 완료)
	private void actionWrite(Request reqeust) {
		System.out.printf("제목 : ");
		String title = Factory.getScanner().nextLine();
		System.out.printf("내용 : ");
		String body = Factory.getScanner().nextLine();

		// 현재 게시판 id 가져오기
		int boardId = Factory.getSession().getCurrentBoard().getId();

		int newId = articleService.write(boardId, title, body);

		System.out.printf("%d번 글이 생성되었습니다.\n", newId);
	}

	// 게시물 수정(DB연동 완료)
	private void actionModify(Request reqeust) {

		System.out.println("== 게시물 수정 시작 ==");
		
		System.out.printf("수정할 게시물 번호 : ");
		int id = Factory.getScanner().nextInt();
		Factory.getScanner().nextLine(); // 스캐너 버퍼 비우기(int 받을 시 버퍼 발생).
		
		if( id > 0 ) {
			articleService.modify(id);
		} else {
			System.out.println("다시 입력해 주세요.");
		}	
		
		System.out.println("== 게시물 수정 끝 ==");
	}

	// 게시물 삭제(DB연동 완료)
	private void actionDelete(Request reqeust) {

		System.out.println("== 게시물 삭제 시작 ==");
		
		System.out.printf("삭제할 게시물 번호 : ");
		int id = Factory.getScanner().nextInt();
		Factory.getScanner().nextLine(); // 스캐너 버퍼 비우기(int 받을 시 버퍼 발생).
		
		if( id > 0 ) {
			articleService.delete(id);
		} else {
			System.out.println("다시 입력해 주세요.");
		}

		System.out.println("== 게시물 삭제 끝 ==");
	}

	// 게시물 리스트(전체)(DB연동 완료)
	private void actionList(Request reqeust) {

		System.out.println("== 게시물 리스트 시작 ==");
		List<Article> articles = articleService.getArticles();
		for (Article article : articles) {
			System.out.printf("id : %d, boardId : %d, regDate : %s, title : %s, body : %s\n", article.getId(),
					article.getBoardId(), article.getRegDate(), article.getTitle(), article.getBody());
		}
		System.out.println("== 게시물 리스트 끝 ==");
	}

	// 게시물 상세보기(DB연동 완료)
	private void actionDetail(Request reqeust) {
		System.out.println("== 게시물 상세보기 시작 ==");
		
		System.out.printf("게시물(상세보기) 번호 : ");
		int id = Factory.getScanner().nextInt();
		Factory.getScanner().nextLine(); // 스캐너 버퍼 비우기(int 받을 시 버퍼 발생).

		articleService.getArticlesDetail(id);

		System.out.println("== 게시물 상세보기 끝 ==");
	}

	// 게시판 변경(DB연동 완료)
	private void actionChangBoard(Request reqeust) {
		System.out.println("== 게시판 변경 시작 ==");
		System.out.println("게시판 목록 = 공지사항 : 'notice' / 자유게시판 : 'free' ");
		System.out.printf("변경할 게시판 : ");
		String name = Factory.getScanner().nextLine();
		if (name.equals("notice")) {
			articleService.getChangeBoard("notice");
		} else if (name.equals("free")) {
			articleService.getChangeBoard("free");
		} else {
			System.out.println("잘못된 명령어 입니다.");
		}
		System.out.println("== 게시판 변경 끝 ==");
	}
	
}

class BuildController extends Controller {
	private BuildService buildService;

	BuildController() {
		buildService = Factory.getBuildService();
	}

	@Override
	void doAction(Request reqeust) {
		if (reqeust.getActionName().equals("site")) {
			actionSite(reqeust);
		} else if (reqeust.getActionName().equals("siteauto")) {
			actionAuto(reqeust);
		} else if (reqeust.getActionName().equals("stop")) {
			actionStop(reqeust);
		}
	}

	// 빌드 사이트(수동)
	private void actionSite(Request reqeust) {
		System.out.println("site 생성 완료");
		buildService.buildSite();
		buildService.creatMain();
		buildService.creatStatistics();
		// 미사용 buildService.actionCreatLogin();
		// 미사용 buildService.actionCreatHead();
	}
	
	// build site 자동 수행
	private void actionAuto(Request reqeust) {
		buildService.startWork();
	}
	
	// build site 자동 수행 종료
	private void actionStop(Request reqeust) {
		buildService.stopWork();		
	}
	
}

// Service
class BuildService {
	ArticleService articleService;
	private int count;
	private int notice_count;
	private int free_count;
	private static boolean worked;

	BuildService() {
		articleService = Factory.getArticleService();
	}

	static {
		worked = false;
	}
	
	// build site 자동 수행
	public void startWork() {
		worked = true;
		new Thread(() -> {
			while(worked) {
				try {
					System.out.println("사이트 자동 생성 진행");
					buildSite();
					creatMain();
					creatStatistics();
					Thread.sleep(10000); // 10초간 일시정지
				} catch(InterruptedException e) {
					
				}
			}
		}).start();	
	}
	
	// build site 자동 수행 종료
	public void stopWork() {
		System.out.println("사이트 자동 생성 종료");
		worked = false;
	}

	// 사이트 통계 화면 생성(각 항목 해당 값만 추가하기)
	public void creatStatistics() {
		
		count = Factory.getDBConnection().selectRowIntValue("SELECT COUNT(id) FROM article");
		notice_count = Factory.getDBConnection().selectRowIntValue("SELECT boardId, COUNT(boardId) AS cnt FROM article WHERE boardId > 1 GROUP BY boardId;");
		free_count = Factory.getDBConnection().selectRowIntValue("SELECT boardId, COUNT(boardId) AS cnt FROM article WHERE boardId < 2 GROUP BY boardId;");
		Util.makeDir("site");
		Util.makeDir("site/article");
		String head = Util.getFileContents("site_template/part/head.html");
		String foot = Util.getFileContents("site_template/part/foot.html");

		String fileName = "Statistics.html";

		String html = "";

		String template = Util.getFileContents("site_template/article/Statistics.html");

		List<Article> articles = articleService.getArticles();

		html += "<h2 class=\"t1-h\">사이트 통계</h2>";
		html += "<table border=1>";
		html += "<thead>";
		html += "<tr>";
		html += "<td class=\"td1\">전체 게시물 수</td>";
		html += "<td colspan=3>" + count + "개</td>";
		html += "</tr>";
		html += "<tr>";
		html += "<td class=\"td1\">공지사항 게시물 수</td>";
		html += "<td colspan=3>" + notice_count + "개</td>";
		html += "</tr>";
		html += "<tr>";
		html += "<td class=\"td1\">자유게시판 게시물 수</td>";
		html += "<td colspan=3>" + free_count + "개</td>";
		html += "</tr>";

		html = template.replace("${TR}", html);

		html = head + html + foot;

		Util.writeFileContents("site/article/" + fileName, html);
	}

	/* 로그인 기능 없으므로 미 사용
	 * 미사용 // 사이트 로그인 화면 생성(생성완료) public void creatLogin() { Util.makeDir("site");
	 * Util.makeDir("site/article"); String head =
	 * Util.getFileContents("site_template/part/head.html"); String foot =
	 * Util.getFileContents("site_template/part/foot.html");
	 * 
	 * String fileName = "login.html";
	 * 
	 * String html = "";
	 * 
	 * String template = Util.getFileContents("site_template/article/login.html");
	 * 
	 * html = template.replace("${TR}", html);
	 * 
	 * html = head + html + foot;
	 * 
	 * Util.writeFileContents("site/article/" + fileName, html); }
	 */

	/*
	// head (게시판 목록 자동생성 관련) - 진행 중
	public void creatHead() {
		Util.makeDir("site");
		Util.makeDir("site/article");

		String head = Util.getFileContents("site_template/part/head.html");
		String foot = Util.getFileContents("site_template/part/foot.html");

		// head 게시판 목록 자동생성 구현 과련
		List<Board> boards = articleService.getBoards();

		for (Board board : boards) {

			String fileName = board.getName() + "-boardList-1.html";

			String html = "";

			String template = Util.getFileContents("site_template/part/head.html");

			html += "<li><a href=" + board.getName() + "-list-1.html>" + board.getName() + "</a></li>";

			html = template.replace("${TR}", html);

			html = head + html + foot;

			Util.writeFileContents("site/article/" + fileName, html);
		}
	}
	*/

	// 사이트 홈 화면 생성(생성완료)
	public void creatMain() {
		Util.makeDir("site");
		Util.makeDir("site/article");
		String head = Util.getFileContents("site_template/part/head.html");
		String foot = Util.getFileContents("site_template/part/foot.html");

		String fileName = "main.html";

		String html = "";

		String template = Util.getFileContents("site_template/article/main.html");

		html += "<style> .main-box {text-align: center; padding: 100px;}";
		html += ".main-box > img{width: 800px; border-radius: 50px;}</style>";

		html += "<nav class=\"main-box\">";
		html += "<img src=\"main\\images\\main1.jpg\" alt=\"\"></nav>";

		html = head + html + foot;

		Util.writeFileContents("site/article/" + fileName, html);

	}

	// 리스트 / 상세보기 사이트 생성
	public void buildSite() {
		Util.makeDir("site");
		Util.makeDir("site/article");

		String head = Util.getFileContents("site_template/part/head.html");
		String foot = Util.getFileContents("site_template/part/foot.html");

		// 각 게시판 별 게시물리스트 페이지 생성(작업 중 - 공지 / 자유 분리하기 )
		List<Board> boards = articleService.getBoards();

		for (Board board : boards) {
			// 존재하는 보드 들의 이름으로 다 만들어진 ( 4개있을 경우 4개 생성 됨 )
			String fileName = board.getName() + "-list-1.html";

			String html = "";

			// article이 모두 들어있음.
			List<Article> articles = articleService.getArticles();

			String template = Util.getFileContents("site_template/article/list.html");

			if (board.getName().equals("notice")) {
				html += "<h2> 공지사항 게시판</h2>";
			} else if (board.getName().equals("free")) {
				html += "<h2> 자유 게시판</h2>";
			} else {
				html += "<h2> " + board.getName() + "게시판</h2>";
			}

			for (Article article : articles) {
				if ((article.getBoardId() == Integer.parseInt(board.getCode()))) {
					if(board.getCode().equals("1")) {
						notice_count++;
					} else if (board.getCode().equals("2")) {
						free_count++;
					}
					html += "<tr>";
					html += "<td>" + article.getId() + "</td>";
					html += "<td><a href=\"" + article.getId() + ".html\">" + article.getTitle() + "</a></td>";
					html += "<td>" + article.getRegDate() + "</td>";
					html += "</tr>";
				}
			}

			html = template.replace("${TR}", html);

			html = head + html + foot;

			Util.writeFileContents("site/article/" + fileName, html);
		}

		// 게시물 별(상세보기) 파일 생성 (완료)
		List<Article> articles = articleService.getArticles();

		for (Article article : articles) {

			String template = Util.getFileContents("site_template/article/detail.html");

			String html = "";

			html += "<h2 class=\"t1-h\">상세보기</h2>";
			html += "<table border=1>";
			html += "<thead>";
			html += "<tr>";
			html += "<td class=\"td1\" colspan=4>게시물 상세보기</td>";
			html += "</tr>";
			html += "<tr>";
			html += "<td class=\"td1\">게시물 번호</td>";
			html += "<td colspan=3>" + article.getId() + "</td>";
			html += "</tr>";
			html += "<tr>";
			html += "<td class=\"td1\">제목</td>";
			html += "<td colspan=3>" + article.getTitle() + "</td>";
			html += "</tr>";
			html += "</tr>";
			html += "<td class=\"td1\">내용</td>";
			html += "<td colspan=3>" + article.getBody() + "</td>";
			html += "</tr>";
			html += "<tr>";
			html += "<td class=\"td1\">작성일자</td>";
			html += "<td colspan=3>" + article.getRegDate() + "</td>";
			html += "</tr>";

			html = template.replace("${TR}", html);

			html = head + html + foot;

			Util.writeFileContents("site/article/" + article.getId() + ".html", html);
		}
	}

}

class ArticleService {
	private ArticleDao articleDao;

	ArticleService() {
		articleDao = Factory.getArticleDao();
	}

	// 게시물 추가(작성)
	public int write(int boardId, String title, String body) {
		Article article = new Article(boardId, title, body);
		return articleDao.save(article);
	}

	// 게시물 수정
	public void modify(int id) {
		articleDao.modify(id);
	}

	// 게시물 삭제
	public void delete(int id) {
		articleDao.delete(id);
	}

	// 게시물 리스트(전체)
	public List<Article> getArticles() {
		return articleDao.getArticles();
	}

	// 게시물 상세보기
	public void getArticlesDetail(int id) {
		articleDao.getArticlesDetail(id);
	}

	// 게시판 변경
	public void getChangeBoard(String boardName) {
		articleDao.changeBoard(boardName);
	}

	// 게시판(Board) 생성
	/*
	public void makeBoard(String boardName, String boardCode) {
		String name = boardName;
		String code = boardCode;

		Board board = new Board(name, code);

		System.out.println("board 생성");

		articleDao.saveBoard(board);
	}
	*/

	/*
	public List<Article> getArticlesByBoardCode(String code) {
		return articleDao.getArticlesByBoardCode(code);
	}
	*/

	public List<Board> getBoards() {
		return articleDao.getBoards();
	}

	public Board getBoard(int id) {
		return articleDao.getBoard(id);
	}

}

// ArticleDao
class ArticleDao {
	DBConnection dbConnection;

	ArticleDao() {
		dbConnection = Factory.getDBConnection();
	}

	// 게시물 추가(DB연동)
	public int save(Article article) {
		String sql = "";
		sql += "INSERT INTO article ";
		sql += String.format("SET regDate = '%s'", article.getRegDate());
		sql += String.format(", title = '%s'", article.getTitle());
		sql += String.format(", `body` = '%s'", article.getBody());
		sql += String.format(", boardId = '%d'", article.getBoardId());

		return dbConnection.insert(sql);
	}

	// 게시물 수정(DB연동)
	public void modify(int id) {

		List<Article> articles = getArticles();

		for (Article article : articles) {
			if (article.getId() == id) {
				System.out.printf("제목 : ");
				String title = Factory.getScanner().nextLine();
				System.out.printf("내용 : ");
				String body = Factory.getScanner().nextLine();

				String sql = "";
				sql += "UPDATE article ";
				sql += String.format("SET title = '%s'", title);
				sql += String.format(", `body` = '%s'", body);
				sql += String.format(" WHERE id = %d", id);

				dbConnection.update(sql);
				System.out.printf("%d번 글이 수정되었습니다.\n", id);
				break;
			}
		}
		
	}

	// 게시물 삭제(DB연동)
	public void delete(int id) {

		List<Article> articles = getArticles();

		for (Article article : articles) {
			if (article.getId() == id) {
				String sql = "";
				sql += "DELETE FROM ";
				sql += String.format("article WHERE id = %d", id);

				dbConnection.delete(sql);
				System.out.printf("%d번 글이 삭제되었습니다.\n", id);
				break;
			}
		}
	}

	// 게시물 리스트(전체)
	public List<Article> getArticles() {
		List<Map<String, Object>> rows = dbConnection.selectRows("SELECT * FROM article ORDER by id DESC");
		List<Article> articles = new ArrayList<>();

		for (Map<String, Object> row : rows) {
			articles.add(new Article(row));
		}

		return articles;
	}

	// 게시물 상세보기
	public void getArticlesDetail(int id) {
		
		List<Article> articles = getArticles();

		for (Article article : articles) {
			if (article.getId() == id) {
				String sql = "";
				sql += "SELECT * FROM article ";
				sql += "WHERE id = " + id;
				
				Map<String, Object> row = dbConnection.selectRow(sql);
				
				System.out.println(row);
				break;
			}
		}
	}

	// 게시판(Board) 변경
	public void changeBoard(String boardName) {
		if (boardName.equals("notice")) {
			System.out.println("게시판 변경 : notice / 게시판 번호 : 1");
			dbConnection.selectRow("SELECT * FROM board WHERE id = " + 1);
			Factory.getSession().setCurrentBoard(Factory.getArticleService().getBoard(1));
		} else if (boardName.equals("free")) {
			System.out.println("게시판 변경 : free / 게시판 번호 : 2");
			dbConnection.selectRow("SELECT * FROM board WHERE id = " + 2);
			Factory.getSession().setCurrentBoard(Factory.getArticleService().getBoard(2));
		}
	}

	/*
	// 게시판(Board) 자동생성(notice, free)
	public void saveBoard(Board board) {
		String sql = "";

		// if문 통해서 null일 때만 생성되도록 했으나, 초기에 아무것도 없는 상태에서는 에러 발생.
		if (board.getCode() == null) {
			sql += "INSERT INTO board ";
			sql += String.format("SET regDate = '%s'", board.getRegDate());
			sql += String.format(", `name` = '%s'", board.getName());
			sql += String.format(", `code` = '%d'", Integer.parseInt(board.getCode()));

			dbConnection.insertBoard(sql);
		}
	}
	*/
	
	// 게시판(Board) 가져오기
	public List<Board> getBoards() {
		List<Map<String, Object>> rows = dbConnection.selectRows("SELECT * FROM board");
		List<Board> boards = new ArrayList<>();

		for (Map<String, Object> row : rows) {
			boards.add(new Board(row));
		}

		return boards;
	}

	// id에 따른 보드 가져오기(에러 발생 주범)
	public Board getBoard(int id) {
		List<Map<String, Object>> rows = dbConnection.selectRows("SELECT * FROM board");

		List<Board> boards = new ArrayList<>();
		Board board = new Board();

		Map<String, Object> row = rows.get(id - 1);

		String regDate = row.get("regDate") + "";
		String code = row.get("code") + "";

		board.setId((int) (long) row.get("id"));
		board.setRegDate(regDate);
		board.setName((String) row.get("name"));
		board.setCode(code);

		return board;
	}
/*
	public List<Article> getArticlesByBoardCode(String code) {
		return db.getArticlesByBoardCode(code);
	}

	public Board getBoardByCode(String code) {
		return db.getBoardByCode(code);
	}
*/
}

/*
// DB
class DB {
	private Map<String, Table> tables;

	public DB() {
		String dbDirPath = getDirPath();
		Util.makeDir(dbDirPath);

		tables = new HashMap<>();

		tables.put("article", new Table<Article>(Article.class, dbDirPath));
		tables.put("board", new Table<Board>(Board.class, dbDirPath));
	}

	public List<Article> getArticlesByBoardCode(String code) {
		Board board = getBoardByCode(code);
		// free => 2
		// notice => 1

		List<Article> articles = getArticles();
		List<Article> newArticles = new ArrayList<>();

		for (Article article : articles) {
			if (article.getBoardId() == board.getId()) {
				newArticles.add(article);
			}
		}

		return newArticles;
	}

	public Board getBoardByCode(String code) {
		List<Board> boards = getBoards();

		for (Board board : boards) {
			if (board.getCode().equals(code)) {
				return board;
			}
		}

		return null;
	}

	public List<Board> getBoards() {
		return tables.get("board").getRows();
	}

	public int saveBoard(Board board) {
		return tables.get("board").saveRow(board);
	}

	public String getDirPath() {
		return "db";
	}

	public Board getBoard(int id) {
		return (Board) tables.get("board").getRow(id);
	}

	public List<Article> getArticles() {
		return tables.get("article").getRows();
	}

	public int saveArticle(Article article) {
		return tables.get("article").saveRow(article);
	}

	public void backup() {
		for (String tableName : tables.keySet()) {
			Table table = tables.get(tableName);
			table.backup();
		}
	}
}

// Table
class Table<T> {
	private Class<T> dataCls;
	private String tableName;
	private String tableDirPath;

	public Table(Class<T> dataCls, String dbDirPath) {
		this.dataCls = dataCls;
		this.tableName = Util.lcfirst(dataCls.getCanonicalName());
		this.tableDirPath = dbDirPath + "/" + this.tableName;

		Util.makeDir(tableDirPath);
	}

	public void backup() {
		// TODO Auto-generated method stub

	}

	private String getTableName() {
		return tableName;
	}

	public int saveRow(T data) {
		Dto dto = (Dto) data;

		if (dto.getId() == 0) {
			int lastId = getLastId();
			int newId = lastId + 1;
			dto.setId(newId);
			setLastId(newId);
		}

		String rowFilePath = getRowFilePath(dto.getId());

		Util.writeJsonFile(rowFilePath, data);

		return dto.getId();
	};

	private String getRowFilePath(int id) {
		return tableDirPath + "/" + id + ".json";
	}

	private void setLastId(int lastId) {
		String filePath = getLastIdFilePath();
		Util.writeFileContents(filePath, lastId);
	}

	private int getLastId() {
		String filePath = getLastIdFilePath();

		if (Util.isFileExists(filePath) == false) {
			int lastId = 0;
			Util.writeFileContents(filePath, lastId);
			return lastId;
		}

		return Integer.parseInt(Util.getFileContents(filePath));
	}

	private String getLastIdFilePath() {
		return this.tableDirPath + "/lastId.txt";
	}

	public T getRow(int id) {
		return (T) Util.getObjectFromJson(getRowFilePath(id), dataCls);
	}

	List<T> getRows() {
		int lastId = getLastId();

		List<T> rows = new ArrayList<>();

		for (int id = 1; id <= lastId; id++) {
			T row = getRow(id);

			if (row != null) {
				rows.add(row);
			}
		}

		return rows;
	};
}
*/

// DTO
abstract class Dto {
	private int id;
	private String regDate;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getRegDate() {
		return regDate;
	}

	public void setRegDate(String regDate) {
		this.regDate = regDate;
	}

	Dto() {
		this(0);
	}

	Dto(int id) {
		this(id, Util.getNowDateStr());
	}

	Dto(int id, String regDate) {
		this.id = id;
		this.regDate = regDate;
	}
}

class Board extends Dto {
	private String name;
	private String code;

	public Board() {
	}

	// 보드 조회(전체)
	public Board(Map<String, Object> row) {

		String regDate = row.get("regDate") + "";
		String code = row.get("code") + "";

		this.setId((int) (long) row.get("id"));
		this.setRegDate(regDate);
		this.setName((String) row.get("name"));
		this.setCode(code);
	}

	public Board(String name, String code) {
		this.name = name;
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

}

class Article extends Dto {
	private int id;
	private int boardId;
	private String title;
	private String body;

	public Article() {

	}

	public Article(String title, String body) {
		this.title = title;
		this.body = body;
	}

	public Article(int boardId, String title, String body) {
		this.boardId = boardId;
		this.title = title;
		this.body = body;
	}

	// 게시물 조회(전체)
	public Article(Map<String, Object> row) {

		String regDate = row.get("regDate") + "";

		this.setId((int) (long) row.get("id"));
		this.setRegDate(regDate);
		this.setTitle((String) row.get("title"));
		this.setBody((String) row.get("body"));
		this.setBoardId((int) (long) row.get("boardId"));
	}

	public int getBoardId() {
		return boardId;
	}

	public void setBoardId(int boardId) {
		this.boardId = boardId;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getBody() {
		return body;
	}

	public void setBody(String body) {
		this.body = body;
	}

	@Override
	public String toString() {
		return "Article [boardId=" + boardId + ", title=" + title + ", body=" + body + ", getId()=" + getId()
				+ ", getRegDate()=" + getRegDate() + "]";
	}

}

class ArticleReply extends Dto {
	private int id;
	private String regDate;
	private int articleId;
	private String body;

	ArticleReply() {

	}

	public int getArticleId() {
		return articleId;
	}

	public void setArticleId(int articleId) {
		this.articleId = articleId;
	}

	public String getBody() {
		return body;
	}

	public void setBody(String body) {
		this.body = body;
	}

}

// Util
class Util {
	// 현재날짜문장
	public static String getNowDateStr() {
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat Date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = Date.format(cal.getTime());
		return dateStr;
	}

	// 파일에 내용쓰기
	public static void writeFileContents(String filePath, int data) {
		writeFileContents(filePath, data + "");
	}

	// 첫 문자 소문자화
	public static String lcfirst(String str) {
		String newStr = "";
		newStr += str.charAt(0);
		newStr = newStr.toLowerCase();

		return newStr + str.substring(1);
	}

	// 파일이 존재하는지
	public static boolean isFileExists(String filePath) {
		File f = new File(filePath);
		if (f.isFile()) {
			return true;
		}

		return false;
	}

	// 파일내용 읽어오기
	public static String getFileContents(String filePath) {
		String rs = null;
		try {
			// 바이트 단위로 파일읽기
			FileInputStream fileStream = null; // 파일 스트림

			fileStream = new FileInputStream(filePath);// 파일 스트림 생성
			// 버퍼 선언
			byte[] readBuffer = new byte[fileStream.available()];
			while (fileStream.read(readBuffer) != -1) {
			}

			rs = new String(readBuffer);

			fileStream.close(); // 스트림 닫기
		} catch (Exception e) {
			e.getStackTrace();
		}

		return rs;
	}

	// 파일 쓰기
	public static void writeFileContents(String filePath, String contents) {
		BufferedOutputStream bs = null;
		try {
			bs = new BufferedOutputStream(new FileOutputStream(filePath));
			bs.write(contents.getBytes()); // Byte형으로만 넣을 수 있음
		} catch (Exception e) {
			e.getStackTrace();
		} finally {
			try {
				bs.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	// Json안에 있는 내용을 가져오기
	public static Object getObjectFromJson(String filePath, Class cls) {
		ObjectMapper om = new ObjectMapper();
		Object obj = null;
		try {
			obj = om.readValue(new File(filePath), cls);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {

		} catch (IOException e) {
			e.printStackTrace();
		}

		return obj;
	}

	public static void writeJsonFile(String filePath, Object obj) {
		ObjectMapper om = new ObjectMapper();
		try {
			om.writeValue(new File(filePath), obj);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void makeDir(String dirPath) {
		File dir = new File(dirPath);
		if (!dir.exists()) {
			dir.mkdir();
		}
	}
}

 

반응형

+ Recent posts