https://mvnrepository.com/artifact/mysql/mysql-connector-java
mysql-connector-java, 메이븐 리포지터리 ↑
- 최신버전(8.0.20) 클릭
- jar 파일 다운로드
[ eclipse 와 SQLyog 연결 순서 ] --> eclipse 와 연결해주기 위해서는 eclipse에 연결 경로로 지정한 DATABASE를
mySQL에서 꼭 CREATE DATABASE [DB명]; 으로 생성해주어야 연결이 된다.
GRANT ALL PRIVILEGES ON *.* TO 'sbsst'@'%' IDENTIFIED BY '****';
GRANT ALL PRIVILEGES ON *.* TO 'sbsst'@'localhost' IDENTIFIED BY '****';
[NOT NULL] : NOT NULL 명시하면 데이터 입력시, 해당 컬럼 데이터에 값이 할당되지 않는 경우를 허락하지 않겠다는 의미
[AUTO_INCREMENT] : AUTO_INCREMENT 명시하면, 해당 테이블에 데이터 등록시 해당 컬럼은 자동으로 숫자가 1씩 증가하여 저장됨
위의 2개 명령어로 아이디와 비밀번호를 생성시킬 수 있다.... 권한을 준다?...
그리고 해당 아이디와 비밀번호로 접속해서 DATABASE를 생성해주고
ECLIPSE와 연결해주면 연결은 되는 듯 하다....
↑ SQLyog 에 root 계정으로 접속한 후, 위의 계정에 권한을 부여해야 한다.
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
*.* --> DATABASE에 있는 모든 TABLE의 권한을 위임하는 행위. --> 이걸로 생성된 id는 MASTER 개념
'%' --> 외부에서 접근 가능하다는 의미
'localhost' --> 로컬에서 접근 가능하다는 의미
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
1. AUTO_INCREMENT : 해당 칼럼값이 연속적인 숫자임을 의미하는 것. --> integer 형이어야 한다.
2. 칼럼을 UNSIGNED 로 선언했다.
--> unsigned를 선언해 주면 그 범위가 양수로 옮겨진다.
-2147483648 ~2147483647 에서 0 ~ 4294967295 로 옮겨가는 것
3. PRIMARY KEY
- 값이 중복되지 않는다.
- 반드시 값을 입력해야 한다. (NOT NULL)
- 테이블 데이터의 고유 인식번호 (id)
[ 예제 해결할 때, 참고할 사항 ]
1. insert 를 return 하면 int (번호)를 반환한다. --> 생성되는 게시물 번호
콘솔에서 빨간색으로 나오는 이유는 try/catch 문에서 System.err.println ~~~~ .err. 로 작성했기 때문에 쿼리 오류를 빨간색으로 보여주는 것.
2. update 를 return하면 수정(변경)된 게시물 개수를 반환한다. int 반환 (사용하는 변수명 : int affectedRows)
WHERE id = 1 -> id가 1인 게시물 // WHERE id IN (1, 2) 의미 : 1번이거나 2번이거나
IN을 사용하지 않으면 WHERE id = 1 OR id = 2 라고 작성해주어야 한다. ==> 1, 2번 둘 다 게시물 수정하겠다.
3. id : 데이터 1개 / id + regDate + title + body : 1개의 묶음
후자는 보통 map 이나 객체 1개로 표현될 수 있다.
map들을 여러개 불러오는 경우 LIST<> 사용하면 된다. (사용한 메서드명 : dbConn.selectRows("SELECT * FROM article");
--> Row가 여러개, 복수개 온다.
== > dbConn.selectRows("SELECT * FROM article LIMIT 2"); --> 1~2번까지 2개의 데이터를 불러온다. 묶음을
4. dbConn.selectRow --> Row가 1개 온다는 것.
5. selectRowIntValue -> SELECT MAX(id) FROM article --> 그룹 함수라고 한다(MAX(id))
--> 사용하지 않으면 낱개로 다 나오지만 그룹화하면 큰거 1개 찾아온다. -> 데이터 1개 의미.
--> 바로 int 값을 받을 수 있다. 편하다.
6. selectRowStringValue ->마지막 String 을 반환한다.
7. selectRowBooleanValue ->
* [ SQLyog ] SELECT 1 = 2 틀린말 --> mySQL에서는 틀린말은 0 이다.
SELECT 1 = 1 맞는말 --> 맞는 말은 1 !
참고 : mySQL은 == 로 표시하지 않는다. ==> 반환값은 boolean 이다.
[ 나중에 삭제할 내용 ]
class DB
class Table
==> Dao에서 설명해주신 내용들을 가지고 mySQL에 일을 시키면 된다.
1. JDBC Driver 설치 ( jar file / 라이브러리 )
https://dev.mysql.com/downloads/connector/j/#downloads 다운로드 링크
사이트 접속 ->
General Availability (GA) Releases - Connector/J 8.0.20 최신버전
Select Operating System: --> Platfrom Independent 선택 ->
Platform Independent (Architecture Independent), Compressed TAR Archive |
다운로드 시작!
또는 https://mvnrepository.com/artifact/mysql/mysql-connector-java
↑여기에 접속해서 다운로드 가능_ maven repository 추천!
2. 다운받은 파일명 mysql-connector-java-8.0.20.jar
해당 파일을 eclipse에 build path 한다.
작업하려는 project 우클릭 -> lib 폴더 생성 -> 해당 파일 복사 붙여 넣기 -> 붙여넣은 파일 선택-> 우클릭 ->
build path 클릭 !
3. eclipse에 연결 코드를 작성한다.
== 1차 == // JDBC 연결
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) {
DBConnection dbConn = new DBConnection();
dbConn.connect();
}
}
class DBConnection {
Connection connection;
public void connect() {
String url = "jdbc:mysql://localhost:3306/site5?serverTimezone=UTC";
String user = "sbsst";
String password = "****";
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 = 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());
}
}
}
== 2차 == // JDBC 연결 종료 ( 2차부터는 1차 코드를 보고나서 참고하기 )
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) {
DBConnection dbConn = new DBConnection();
dbConn.connect();
dbConn.close();
}
}
class DBConnection {
Connection connection;
public void connect() {
String url = "jdbc:mysql://localhost:3306/site5?serverTimezone=UTC";
String user = "sbsst";
String password = "****";
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 = 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());
}
}
public void close() {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
System.out.println("[닫기 오류]\n" + e.getStackTrace());
}
}
}
== 3차 == // 게시물 작성 // SQL 함께 진행
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
public static void main(String[] args) {
DBConnection dbConn = new DBConnection();
dbConn.connect();
dbConn.insert("INSERT INTO article SET regDate = NOW(), title = '제목', `body` = '내용';");
dbConn.close();
}
}
class DBConnection {
Connection connection;
public void connect() {
String url = "jdbc:mysql://localhost:3306/site5?serverTimezone=UTC";
String user = "sbsst";
String password = "****";
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 = 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());
}
}
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 void close() {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
System.out.println("[닫기 오류]\n" + e.getStackTrace());
}
}
}
DROP DATABASE IF EXISTS site5;
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
);
== 4차 == //
- 예외 메세지 출력을 System.out에서 System.err로 변경
- SQL 관련에러에서, SQL 출력하도록
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
public static void main(String[] args) {
DBConnection dbConn = new DBConnection();
dbConn.connect();
dbConn.insert("INSERT INTO article SET regDate = NOW(), title = '제목', `body` = '내용';");
dbConn.update("UPDATE article SET title = '수정된 제목 1' WHERE id = 1");
dbConn.close();
}
}
class DBConnection {
Connection connection;
public void connect() {
String url = "jdbc:mysql://localhost:3306/site5?serverTimezone=UTC";
String user = "sbsst";
String password = "****";
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 = 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());
}
}
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 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.err.printf("[INSERT 쿼리 오류, %s]\n" + e.getStackTrace() + "\n", "sql");
}
try {
if (statement != null) {
statement.close();
}
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
System.err.println("[INSERT 종료 오류]\n" + e.getStackTrace());
}
return id;
}
public void close() {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
System.err.println("[닫기 오류]\n" + e.getStackTrace());
}
}
}
== 5차 ==
- 예외 메세지 출력을 System.out에서 System.err로 변경
- SQL 관련에러에서, SQL 출력하도록
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.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) {
DBConnection dbConn = new DBConnection();
dbConn.connect();
dbConn.insert("INSERT INTO article SET regDate = NOW(), title = '제목', `body` = '내용';");
dbConn.update("UPDATE article SET title = '수정된 제목 1' WHERE id = 1");
List<Map<String, Object>> articlesRows = dbConn.selectRows("SELECT * FROM article");
System.out.println("== 게시물들 ==");
System.out.println(articlesRows);
Map<String, Object> articleRow = dbConn.selectRow("SELECT * FROM article LIMIT 1");
System.out.println("== 게시물 ==");
System.out.println(articleRow);
int lastId = dbConn.selectRowIntValue("SELECT MAX(id) FROM article");
System.out.println("== 최근 게시물 ID ==");
System.out.println(lastId);
String lastTitle = dbConn.selectRowStringValue("SELECT title FROM article ORDER BY id DESC LIMIT 1");
System.out.println("== 최근 게시물 제목 ==");
System.out.println(lastTitle);
boolean lastIdIsOdd = dbConn.selectRowBooleanValue("SELECT id % 2 != 0 FROM article ORDER BY id DESC LIMIT 1");
System.out.println("== 최근 게시물 번호가 홀수인지 ==");
System.out.println(lastIdIsOdd);
dbConn.close();
}
}
class DBConnection {
Connection connection;
public void connect() {
String url = "jdbc:mysql://localhost:3306/site5?serverTimezone=UTC";
String user = "sbsst";
String password = "****";
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 = 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());
}
}
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;
}
public String selectRowStringValue(String sql) {
Map<String, Object> row = selectRow(sql);
for (String key : row.keySet()) {
Object value = row.get(key);
return value + "";
}
return "";
}
public boolean selectRowBooleanValue(String sql) {
int rs = selectRowIntValue(sql);
return rs == 1;
}
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;
}
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 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.err.printf("[INSERT 쿼리 오류, %s]\n" + e.getStackTrace() + "\n", sql);
}
try {
if (statement != null) {
statement.close();
}
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
System.err.println("[INSERT 종료 오류]\n" + e.getStackTrace());
}
return id;
}
public void close() {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
System.err.println("[닫기 오류]\n" + e.getStackTrace());
}
}
}
- JDBC 기초 끝
- 기존 파일 MVC 게시판에 JDBC 적용 시작
- 예제 1, 게시물 저장, 게시물 리스팅에 JDBC 적용
참고 예제.
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();
}
}
// Session
// 현재 사용자가 이용중인 정보
// 이 안의 정보는 사용자가 프로그램을 사용할 때 동안은 계속 유지된다.
class Session {
private Member loginedMember;
private Board currentBoard;
public Member getLoginedMember() {
return loginedMember;
}
public void setLoginedMember(Member loginedMember) {
this.loginedMember = loginedMember;
}
public Board getCurrentBoard() {
return currentBoard;
}
public void setCurrentBoard(Board currentBoard) {
this.currentBoard = currentBoard;
}
public boolean isLogined() {
return loginedMember != null;
}
}
// DB 커넥션(진짜 DB와의 연결을 담당)
class DBConnection {
private Connection connection;
public void connect() {
String url = "jdbc:mysql://localhost:3306/site5?serverTimezone=UTC";
String user = "sbsst";
String password = "****";
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 = 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());
}
}
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;
}
public String selectRowStringValue(String sql) {
Map<String, Object> row = selectRow(sql);
for (String key : row.keySet()) {
Object value = row.get(key);
return value + "";
}
return "";
}
public boolean selectRowBooleanValue(String sql) {
int rs = selectRowIntValue(sql);
return rs == 1;
}
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;
}
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 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.err.printf("[INSERT 쿼리 오류, %s]\n" + e.getStackTrace() + "\n", sql);
}
try {
if (statement != null) {
statement.close();
}
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
System.err.println("[INSERT 종료 오류]\n" + e.getStackTrace());
}
return id;
}
public void close() {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
System.err.println("[닫기 오류]\n" + e.getStackTrace());
}
}
}
// Factory
// 프로그램 전체에서 공유되는 객체 리모콘을 보관하는 클래스
class Factory {
private static Session session;
private static DB db;
private static DBConnection dbConnection;
private static BuildService buildService;
private static ArticleService articleService;
private static ArticleDao articleDao;
private static MemberService memberService;
private static MemberDao memberDao;
private static Scanner scanner;
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;
}
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 MemberService getMemberService() {
if (memberService == null) {
memberService = new MemberService();
}
return memberService;
}
public static MemberDao getMemberDao() {
if (memberDao == null) {
memberDao = new MemberDao();
}
return memberDao;
}
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());
controllers.put("member", new MemberController());
}
public App() {
// 컨트롤러 등록
initControllers();
Factory.getDBConnection().connect();
// 관리자 회원 생성
Factory.getMemberService().join("admin", "admin", "관리자");
// 공지사항 게시판 생성
Factory.getArticleService().makeBoard("공지시항", "notice");
// 자유 게시판 생성
Factory.getArticleService().makeBoard("자유게시판", "free");
// 현재 게시판을 1번 게시판으로 선택
Factory.getSession().setCurrentBoard(Factory.getArticleService().getBoard(1));
// 임시 : 현재 로그인 된 회원은 1번 회원으로 지정, 이건 나중에 회원가입, 로그인 추가되면 제거해야함
Factory.getSession().setLoginedMember(Factory.getMemberService().getMember(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);
}
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);
}
class ArticleController extends Controller {
private ArticleService articleService;
ArticleController() {
articleService = Factory.getArticleService();
}
public void doAction(Request reqeust) {
if (reqeust.getActionName().equals("list")) {
actionList(reqeust);
} else if (reqeust.getActionName().equals("write")) {
actionWrite(reqeust);
}
}
private void actionList(Request reqeust) {
List<Article> articles = articleService.getArticles();
System.out.println("== 게시물 리스트 시작 ==");
for (Article article : articles) {
System.out.printf("%d, %s, %s\n", article.getId(), article.getRegDate(), article.getTitle());
}
System.out.println("== 게시물 리스트 끝 ==");
}
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();
// 현재 로그인한 회원의 id 가져오기
int memberId = Factory.getSession().getLoginedMember().getId();
int newId = articleService.write(boardId, memberId, title, body);
System.out.printf("%d번 글이 생성되었습니다.\n", newId);
}
}
class BuildController extends Controller {
private BuildService buildService;
BuildController() {
buildService = Factory.getBuildService();
}
@Override
void doAction(Request reqeust) {
if (reqeust.getActionName().equals("site")) {
actionSite(reqeust);
}
}
private void actionSite(Request reqeust) {
buildService.buildSite();
}
}
class MemberController extends Controller {
private MemberService memberService;
MemberController() {
memberService = Factory.getMemberService();
}
void doAction(Request reqeust) {
if (reqeust.getActionName().equals("logout")) {
actionLogout(reqeust);
} else if (reqeust.getActionName().equals("login")) {
actionLogin(reqeust);
} else if (reqeust.getActionName().equals("whoami")) {
actionWhoami(reqeust);
} else if (reqeust.getActionName().equals("join")) {
actionJoin(reqeust);
}
}
private void actionJoin(Request reqeust) {
}
private void actionWhoami(Request reqeust) {
Member loginedMember = Factory.getSession().getLoginedMember();
if (loginedMember == null) {
System.out.println("나그네");
} else {
System.out.println(loginedMember.getName());
}
}
private void actionLogin(Request reqeust) {
System.out.printf("로그인 아이디 : ");
String loginId = Factory.getScanner().nextLine().trim();
System.out.printf("로그인 비번 : ");
String loginPw = Factory.getScanner().nextLine().trim();
Member member = memberService.getMemberByLoginIdAndLoginPw(loginId, loginPw);
if (member == null) {
System.out.println("일치하는 회원이 없습니다.");
} else {
System.out.println(member.getName() + "님 환영합니다.");
Factory.getSession().setLoginedMember(member);
}
}
private void actionLogout(Request reqeust) {
Member loginedMember = Factory.getSession().getLoginedMember();
if (loginedMember != null) {
Session session = Factory.getSession();
System.out.println("로그아웃 되었습니다.");
session.setLoginedMember(null);
}
}
}
// Service
class BuildService {
ArticleService articleService;
BuildService() {
articleService = Factory.getArticleService();
}
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) {
String fileName = board.getCode() + "-list-1.html";
String html = "";
List<Article> articles = articleService.getArticlesByBoardCode(board.getCode());
String template = Util.getFileContents("site_template/article/list.html");
for (Article article : articles) {
html += "<tr>";
html += "<td>" + article.getId() + "</td>";
html += "<td>" + article.getRegDate() + "</td>";
html += "<td><a href=\"" + article.getId() + ".html\">" + article.getTitle() + "</a></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 html = "";
html += "<div>제목 : " + article.getTitle() + "</div>";
html += "<div>내용 : " + article.getBody() + "</div>";
html += "<div><a href=\"" + (article.getId() - 1) + ".html\">이전글</a></div>";
html += "<div><a href=\"" + (article.getId() + 1) + ".html\">다음글</a></div>";
html = head + html + foot;
Util.writeFileContents("site/article/" + article.getId() + ".html", html);
}
}
}
class ArticleService {
private ArticleDao articleDao;
ArticleService() {
articleDao = Factory.getArticleDao();
}
public List<Article> getArticlesByBoardCode(String code) {
return articleDao.getArticlesByBoardCode(code);
}
public List<Board> getBoards() {
return articleDao.getBoards();
}
public int makeBoard(String name, String code) {
Board oldBoard = articleDao.getBoardByCode(code);
if (oldBoard != null) {
return -1;
}
Board board = new Board(name, code);
return articleDao.saveBoard(board);
}
public Board getBoard(int id) {
return articleDao.getBoard(id);
}
public int write(int boardId, int memberId, String title, String body) {
Article article = new Article(boardId, memberId, title, body);
return articleDao.save(article);
}
public List<Article> getArticles() {
return articleDao.getArticles();
}
}
class MemberService {
private MemberDao memberDao;
MemberService() {
memberDao = Factory.getMemberDao();
}
public Member getMemberByLoginIdAndLoginPw(String loginId, String loginPw) {
return memberDao.getMemberByLoginIdAndLoginPw(loginId, loginPw);
}
public int join(String loginId, String loginPw, String name) {
Member oldMember = memberDao.getMemberByLoginId(loginId);
if (oldMember != null) {
return -1;
}
Member member = new Member(loginId, loginPw, name);
return memberDao.save(member);
}
public Member getMember(int id) {
return memberDao.getMember(id);
}
}
// Dao
class ArticleDao {
DB db;
DBConnection dbConnection;
ArticleDao() {
db = Factory.getDB(); // 나중에 없어질
dbConnection = Factory.getDBConnection();
}
public List<Article> getArticlesByBoardCode(String code) {
return db.getArticlesByBoardCode(code);
}
public List<Board> getBoards() {
return db.getBoards();
}
public Board getBoardByCode(String code) {
return db.getBoardByCode(code);
}
public int saveBoard(Board board) {
return db.saveBoard(board);
}
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(", memberId = '%d'", article.getMemberId());
sql += String.format(", boardId = '%d'", article.getBoardId());
return dbConnection.insert(sql);
}
public Board getBoard(int id) {
return db.getBoard(id);
}
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;
// return db.getArticles();
}
}
class MemberDao {
DB db;
MemberDao() {
db = Factory.getDB();
}
public Member getMemberByLoginIdAndLoginPw(String loginId, String loginPw) {
return db.getMemberByLoginIdAndLoginPw(loginId, loginPw);
}
public Member getMemberByLoginId(String loginId) {
return db.getMemberByLoginId(loginId);
}
public Member getMember(int id) {
return db.getMember(id);
}
public int save(Member member) {
return db.saveMember(member);
}
}
// 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));
tables.put("member", new Table<Member>(Member.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 Member getMemberByLoginIdAndLoginPw(String loginId, String loginPw) {
List<Member> members = getMembers();
for (Member member : members) {
if (member.getLoginId().equals(loginId) && member.getLoginPw().equals(loginPw)) {
return member;
}
}
return null;
}
public Member getMemberByLoginId(String loginId) {
List<Member> members = getMembers();
for (Member member : members) {
if (member.getLoginId().equals(loginId)) {
return member;
}
}
return null;
}
public List<Member> getMembers() {
return tables.get("member").getRows();
}
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 Member getMember(int id) {
return (Member) tables.get("member").getRow(id);
}
public int saveBoard(Board board) {
return tables.get("board").saveRow(board);
}
public String getDirPath() {
return "db";
}
public int saveMember(Member member) {
return tables.get("member").saveRow(member);
}
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);
}
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);
}
public void backup() {
}
void delete(int id) {
/* 구현 */
};
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(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 boardId;
private int memberId;
private String title;
private String body;
public Article() {
}
public Article(int boardId, int memberId, String title, String body) {
this.boardId = boardId;
this.memberId = memberId;
this.title = title;
this.body = body;
}
public Article(Map<String, Object> row) {
this.setId((int) (long) row.get("id"));
String regDate = row.get("regDate") + "";
this.setRegDate(regDate);
this.setTitle((String) row.get("title"));
this.setBody((String) row.get("body"));
this.setMemberId((int) (long) row.get("memberId"));
this.setBoardId((int) (long) row.get("boardId"));
}
public int getBoardId() {
return boardId;
}
public void setBoardId(int boardId) {
this.boardId = boardId;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
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 + ", memberId=" + memberId + ", title=" + title + ", body=" + body
+ ", getId()=" + getId() + ", getRegDate()=" + getRegDate() + "]";
}
}
class ArticleReply extends Dto {
private int id;
private String regDate;
private int articleId;
private int memberId;
private String body;
ArticleReply() {
}
public int getArticleId() {
return articleId;
}
public void setArticleId(int articleId) {
this.articleId = articleId;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
class Member extends Dto {
private String loginId;
private String loginPw;
private String name;
public Member() {
}
public Member(String loginId, String loginPw, String name) {
this.loginId = loginId;
this.loginPw = loginPw;
this.name = name;
}
public String getLoginId() {
return loginId;
}
public void setLoginId(String loginId) {
this.loginId = loginId;
}
public String getLoginPw() {
return loginPw;
}
public void setLoginPw(String loginPw) {
this.loginPw = loginPw;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// 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();
}
}
}
'IT 유용한 정보' 카테고리의 다른 글
2020-06-24 수요일 수업_jsp 사용법 (0) | 2020.06.25 |
---|---|
톰캣설명, 톰캣 개발환경셋팅 (0) | 2020.06.24 |
SQLyog 사용법(명령어 종류, 예제) (0) | 2020.06.16 |
VISUAL STUDIO CODE, XAMPP, SQLyog Community Edition 설치 (0) | 2020.06.16 |
HTML 한글 깨짐 방지(해결 방법)_이클립스 (0) | 2020.06.11 |