else if (cmd.equals("article list")) {
System.out.println("== 게시물 리스트 ==");
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet result = null;
List<Article> articles = new ArrayList<>();
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/article_manager?useUnicode=true&char acterEncoding=utf8&autoReconnect=true&serverTimezone=
Asia/Seoul&useOldAliasMetadataBehavior=true&zeroDateTimeNehavior=convertToNull";
conn = DriverManager.getConnection(url, "root", "");
System.out.println("연결 성공!");
String sql = "SELECT * FROM article";
sql += " ORDER BY id DESC;";
System.out.println(sql);
pstmt = conn.prepareStatement(sql);
result = pstmt.executeQuery();
while (result.next()) {
int id = result.getInt("id");
String regDate = result.getString("regDate");
String updateDate = result.getString("updateDate");
String title = result.getString("title");
String body = result.getString("body");
Article article = new Article(id, regDate, updateDate, title, body);
articles.add(article);
}
} catch (ClassNotFoundException e) {
System.out.println("드라이버 로딩 실패");
} catch (SQLException e) {
System.out.println("에러: " + e);
} finally {
try {
if (result != null && !result.isClosed()) {
result.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (pstmt != null && !pstmt.isClosed()) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
if (articles.size() == 0) {
System.out.println("게시물이 없습니다.");
continue;
}
System.out.println("번호 / 제목");
for (Article article : articles) {
System.out.printf("%d / %s\n", article.id, article.title);
}
}
1) 실행할 sql문 작성 , 쿼리문 실행후 결과 값을 result로
String sql = "SELECT * FROM article";
sql += " ORDER BY id DESC;";
System.out.println(sql);
pstmt = conn.prepareStatement(sql);
result = pstmt.executeQuery();
2) executeQuery() 메소드는 결과로 ResultSet을 반환,이 ResultSet으로부터 원하는 데이터를 추출
ResultSet에는 SELECT된 로우의 데이터 값들이 저장되어있다.
데이터를 추출하는 방법은 ResultSet에서 한 행씩 이동하면서 get...()를 이용하여 원하는 필드 값을 추출하는데,
이때 result.getString("name") 혹은 rs.getString(1)을 사용한다 (필드명을 쓰거나 칼럼 순서대로 숫자를 쓰거나)
ResultSet의 첫 번째 필드는 1부터 시작한다.
한 행이 처리되고 다음 행으로 이동 시 next() 메소드를 사용한다.
ResultSet.getXXX(int columnIndex 또는 String columnName)
** next() : 커서가 BOF(Begin Of File)에서 시작해 EOF(End Of File)에 닿을 때까지 이동하며 커서 위치에 행이 존재하는지 판단하여, boolean값을 반환하는 메소드
while (result.next()) {
int id = result.getInt("id");
String regDate = result.getString("regDate");
String updateDate = result.getString("updateDate");
String title = result.getString("title");
String body = result.getString("body");
Article article = new Article(id, regDate, updateDate, title, body);
articles.add(article);
}
3) JDBC 객체 연결 해제 result객체도 Statement객체와 같이 연결을 해제 시켜줘야한다.
try {
if (result != null && !result.isClosed()) {
result.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
| 메소드 종류 | 반환 자료형 | 특징 |
|---|---|---|
| executeQuery() | ResultSet | SELECT와 같이 데이터베이스에 변경을 주지 않는 SQL 문장을 실행할 때 사용하며 그 결과로 ResultSet 객체를 반환 |
| executeUpdate() | int | INSERT, UPDATE, DELETE와 같이 데이터베이스 구조 또는 값을 변경시키는 질의(DML), CREATE, DROP과 같은 DDL 구문을 사용할 때 사용한다 질의 수행 후 영향을 받은 행의 수를 정수로 반환한다 |
| execute() | boolean | 실행할 SQL문이 어떠한 종류의 것인지 모를 경우에 사용한다 결과가 ResultSet이면 true, 결과가 행의 수 이거나 없으면 false를 반환한다 |
1) INSERT,SELECT와 작성방식이 동일하다. 수정에서는 새로 채워질 제목과 내용을받고
else if (cmd.startsWith("article modify ")) {
int id = Integer.parseInt(cmd.split(" ")[2]);
System.out.printf("== %d번 게시물 수정 ==\n", id);
Connection conn = null;
PreparedStatement pstmt = null;
System.out.printf("새 제목 : ");
String title = sc.nextLine();
System.out.printf("새 내용 : ");
String body = sc.nextLine();
2) executeUpdate() 메소드를 통해 UPDATE, 이때 수정할 로우의 id값을 조건으로 걸어줌.
String sql = "UPDATE article";
sql += " SET title = " + "'" + title + "'";
sql += ", `body` = " + "'" + body + "'";
sql += " WHERE id = " + id + ";";
System.out.println(sql);
pstmt = conn.prepareStatement(sql);
pstmt.executeUpdate();
기존 JAVA게시판과 같은 방식으로 Main에 모든 코드가 작성되고 있으므로 App클래스로 이전하여 리팩토링할 예정.
while (true) {
System.out.printf("명령어 ) ");
String cmd = sc.nextLine().trim();
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("예외 : 클래스가 없습니다.");
System.out.println("프로그램을 종료합니다.");
break;
}
String url = "jdbc:mysql://127.0.0.1:3306/article_manager? useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul&useOl
dAliasMetadataBehavior=true&zeroDateTimeNehavior=convertToNull";
try {
conn = DriverManager.getConnection(url, "root", "");
int actionResult = doAction(conn, sc, cmd);
if (actionResult == -1) {
System.out.println("프로그램 종료");
break;
}
} catch (SQLException e) {
System.out.println("@@@@에러@@@@" + e);
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
sc.close();
}
try catch 문을 두 개로 분류
1) 첫번째 try catch문 에서 Driver 연결만 시도
각각의 기능의 내부에서 드라이버 연결을 하지않고 명령어 입력시 JDBC Driver 연결
ClassNotFoundException 예외 처리
드라이버 클래스가 없을시(드라이버 로드가 안될때)
break;
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("예외 : 클래스가 없습니다.");
System.out.println("프로그램을 종료합니다.");
break;
}
2) 드라이버 로드가 됬다면 두번째 try catch문 에서는 DB 연결 시도하고 doAction()에 인자로 conn,sc,cmd를 전달하여
반환값이 -1(명령어가 exit 일때, 나머지는 return 0;) 이되면 반복문 종료
try {
conn = DriverManager.getConnection(url, "root", "");
int actionResult = doAction(conn, sc, cmd);
if (actionResult == -1) {
System.out.println("프로그램 종료");
break;
}
3) 아래 코드 내용은 doAction() 안의 write중 , conn객체의 종료는 doAction() 실행후 종료하게 하였으므로 각각의 pstmt와 result객체만 종료하게 함
pstmt = conn.prepareStatement(sql); 실행시 SQLException가 throws 되었으므로 try catch로 예외처리
나머지 modify,list도 이와 비슷한 방식으로 처리
if (cmd.equals("article write")) {
System.out.println("== 게시물 작성 ==");
System.out.printf("제목 : ");
String title = sc.nextLine();
System.out.printf("내용 : ");
String body = sc.nextLine();
PreparedStatement pstmt = null;
try {
String sql = "INSERT INTO article";
sql += " SET regDate = NOW()";
sql += ",updateDate = NOW()";
sql += ",title = '" + title + "'";
sql += ",`body` = '" + body + "';";
System.out.println(sql);
pstmt = conn.prepareStatement(sql);
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println("@@@@에러@@@@: " + e);
} finally {
try {
if (pstmt != null && !pstmt.isClosed()) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}