이것이 자바다 18일차 - Chapter20 데이터베이스 입출력

Seo-Faper·2023년 2월 2일
0

이것이 자바다

목록 보기
19/20
post-custom-banner

JDBC 개요

자바는 데이터베이스와 연결해서 데이터 입출력 작업을 할 수 있도록 JDBC(JavaDatabaseConnectivity)라이브러리를 제공한다.

JDBC는 데이터베이스 관리시스템 (DBMS)의 종류와 상관없이 동일하게 사용할 수 있는 클래스와 인터페이스로 구성되어있다.

DBMS의 종류에는 Oracle, MySql, MariaDB 등이 있는데, 여기선 MySql을 사용할 것이다.

JDBC에 포함되어 있는 클래스와 인터페이스들은 다음과 같다.

DriverManager

  • JDBC Driver를 관리하며 DB와 연결해서 Connection 구현 객체를 생성한다.
  • 여기서 JDBD Driver란 MySql을 쓰기 때문에 MySql이 된다.

Connection

  • Connection 인터페이스는 Statement, PreparedStatement, CallableStatement 구현 객체를 생성하며, 트랜잭션 처리 및 DB 연결을 끊을 때 사용한다.

Statement

  • SQL의 DDL과 DML을 실행할 때 사용한다. 주로 변경되지 않는 정적 SQl문을 실행할 때 사용한다.

PreparedStatement

  • PreparedStatement는 Statement와 동일하게 SQL의 DDL, DML 문을 실행할 때 사용한다. 차이점은 매개변수화된 SQL문을 쓸 수 있기 때문에 편리성과 보안성이 좋다.

CallableStatement

  • DB에 저장되어 있는 프로시저와 함수를 호출할 때 사용한다.

ResultSet

  • DB에서 가져온 데이터를 읽을 때 사용한다.

DB 연결

package ch20.mysql.sec05;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionExample {
    public static void main(String[] args) {
        Connection conn = null;

        try {
//JDBC Driver 등록
            Class.forName("com.mysql.cj.jdbc.Driver");

            conn = DriverManager.getConnection(
                     "jdbc:mysql://localhost:3306/thisisjava",
                     "java",
                     "mysql"
                     );

             System.out.println("연결 성공");

             } catch (ClassNotFoundException e) {
             e.printStackTrace();
             } catch (SQLException e) {
             e.printStackTrace();
             } finally {
             if(conn != null) {
                 try {
                     //연결 끊기
                     conn.close();
                     System.out.println("연결 끊기");
                     } catch (SQLException e) {}
                 }
        }
    }
}

데이터 저장

INSERT INTO users (userid, username, userpassword, userage, useremail)
VALUES ('winter', '한겨울', '12345', 25, 'winter@mycompany.com')

이런 쿼리문이 있다.
이 것을 ?(물음표)로 대체한 매개변수화된 INSERT 문으로 변경하면 다음과 같다.

INSERT INTO users (userid, username, userpassword, userage, useremail)
VALUES (?, ?, ?, ?, ?)

그리고 이걸 String 타입으로 바꾸면 다음과 같다.

String sql = new StringBuilder()
.append("INSERT INTO users (userid, username, userpassword, userage, useremail) ")
.append("VALUES (?, ?, ?, ?, ?)")
.toString();

매개변수화 SQL을 실행하려면 PreparedStatement을 쓰면 된다.

PreparedStatement pstmt = conn.prepareStatement(sql);

pstmt.setString(1, "winter");
pstmt.setString(2, "한겨울");
pstmt.setString(3, "12345");
pstmt.setInt(4, 25);
pstmt.setString(5, "winter@mycompany.com");
package ch20.mysql.sec06;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class UserInsertExample {
    public static void main(String[] args) {
        Connection conn = null;

        try {
        //JDBC Driver 등록
            Class.forName("com.mysql.cj.jdbc.Driver");

            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/thisisjava",
                    "root",
                    "mysql"
            );

            System.out.println("연결 성공");
            String sql = "" +
                    "INSERT INTO users (userid, username, userpassword, userage, useremail) " +
                    "VALUES (?, ?, ?, ?, ?)";

            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,"winter");
            pstmt.setString(2, "한겨울");
            pstmt.setString(3, "12345");
            pstmt.setInt(4, 25);
            pstmt.setString(5, "winter@mycompany.com");

            int rows = pstmt.executeUpdate();
            System.out.println("저장된 행 수 : "+rows);
            pstmt.close();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if(conn != null) {
                try {
                    //연결 끊기
                    conn.close();
                    System.out.println("연결 끊기");
                } catch (SQLException e) {}
            }
        }
    }
}

데이터 수정

게시판에 글을 썼다고 가정하면 다음과 같이 정보를 입력할 수 있다.

package ch20.mysql.sec06;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.*;

public class BoardWithFileInsertExample {
    public static void main(String[] args) {
        Connection conn = null;

        try {
            //JDBC Driver 등록
            Class.forName("com.mysql.cj.jdbc.Driver");

            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/thisisjava",
                    "root",
                    "mysql"
            );

            String sql = "" +
                    "INSERT INTO boards (btitle, bcontent, bwriter, bdate, bfilename, bfiledata) " +
             "VALUES (?, ?, ?, now(), ?, ?)";

            PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            pstmt.setString(1,"눈 오는 날");
            pstmt.setString(2,"함박눈이 내려요.");
            pstmt.setString(3,"winter");
            pstmt.setString(4,"snowman.jpg");
            pstmt.setBlob(5, new FileInputStream("src/ch20/mysql/sec06/snowman.jpg"));
            int rows = pstmt.executeUpdate();
            System.out.println("수정된 행 수 : "+rows);


             if(rows == 1) {
                ResultSet rs = pstmt.getGeneratedKeys();
                if(rs.next()) {
                     int bno = rs.getInt(1);
                     System.out.println("저장된 bno: " + bno);
                     }
                 rs.close();
             }
        } catch (ClassNotFoundException | FileNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if(conn != null) {
                try {
                    //연결 끊기
                    conn.close();
                    System.out.println("연결 끊기");
                } catch (SQLException e) {}
            }
        }
    }
}

기존에 데이터 저장 기능(INSERT)을 통해 테이블에 값이 담겨 있는 상태라면
UPDATE 키워드를 통해 수정 할 수 있다.

package ch20.mysql.sec07;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class BoardUpdateExample {
    public static void main(String[] args) {
        Connection conn = null;

        try {
            //JDBC Driver 등록
            Class.forName("com.mysql.cj.jdbc.Driver");

            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/thisisjava",
                    "root",
                    "mysql"
            );

            String sql = new StringBuilder()
                    .append("UPDATE boards SET ")
                    .append("btitle=?, ")
                    .append("bcontent=?, ")
                    .append("bfilename=?, ")
                    .append("bfiledata=? ")
                    .append("WHERE bno=?")
                    .toString();

            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,"눈사람");
            pstmt.setString(2,"눈으로 만든 사람");
            pstmt.setString(3,"snowman.jpg");
            pstmt.setBlob(4, new FileInputStream("src/ch20/mysql/sec07/snowman.jpg"));
            pstmt.setInt(5,2);
            int rows = pstmt.executeUpdate();
            System.out.println("수정된 행 수 : "+rows);
        } catch (ClassNotFoundException | FileNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if(conn != null) {
                try {
                    //연결 끊기
                    conn.close();
                    System.out.println("연결 끊기");
                } catch (SQLException e) {}
            }
        }
    }

}

WHERE bno= ? 를 통해 특정 게시물 번호를 정하고 해당 번호의 칼럼을 지정된 값으로 바꾸는 코드 이다.

데이터 삭제

DELETE 키워드를 통해 해당 칼럼을 삭제 할 수 있다.

package ch20.mysql.sec08;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class BoardDeleteExample {
    public static void main(String[] args) {
        Connection conn = null;

        try {
//JDBC Driver 등록
            Class.forName("com.mysql.cj.jdbc.Driver");

            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/thisisjava",
                    "root",
                    "mysql"
            );

            String sql = "DELETE FROM boards WHERE bwriter=?";

            PreparedStatement psmt = conn.prepareStatement(sql);
            psmt.setString(1,"winter");

            int rows = psmt.executeUpdate();
            System.out.println("삭제된 행 수 : "+rows);

            psmt.close();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if(conn != null) {
                try {
                    //연결 끊기
                    conn.close();
                    System.out.println("연결 끊기");
                } catch (SQLException e) {}
            }
        }
    }
}

데이터 읽기

SQl 문이 추가, 수정, 삭제 일 때는 executeUpdate() 메소드를 호출하지만, 데이터를 가져오는 SELECT 일 때는 executeQuery() 메소드를 써야 한다.

ResultSet rs = pstmt.executeQuery();

ResultSet 구조

ResultSet 이란 SELECT 문에 의해 선택된 칼럼으로 구성된 행(row)의 집합이다.

SELECT userid, username, userage FROM users

예를 들어 이 users라는 테이블에서 저 쿼리문을 실행하면 다음과 같이 구성된다.

ResultSet의 특징은 커서cursor가 있는 행의 데이터만 읽을 수 있다는 것이다.
여기서 커서는 행을 가리키는 포인터를 말한다.
ResultSet은 실제 가져온 데이터 행의 앞과 뒤에 beforeFirst 행과 afterLast 행이 붙는데, 최초 커서는 beforeFirst를 가리킨다. 따라서 첫 번째 데이터 행인 first 행을 읽으려면 커서를 이동시켜야 한다. 이때 next() 메소드를 사용한다.

boolean result = rs.next();

행이 하나만 있을 경우에는 다음과 같이 쓸 수 있다.

ResultSet rc = pstmt.executeQuery();
if(rs.next()) {
	//첫번째 데이터 행 처리
} else {
	//afterLast 행으로 이동했을 경우
}

n개의 다이터 행을 가져올 경우

ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
 //last 행까지 이동하면서 데이터 행 처리
}
 //afterLast 행으로 이동했을 경우

SELECT문을 사용하고 난 뒤는 close()를 통해 사용한 메모리를 해제하는 것이 좋다.
SELECT문은 조건식에 따라 많은 데이터 행을 저장할 수 있기 때문이다.

package ch20.mysql.sec09.exam01;

import java.sql.*;

public class UserSelectExample {
    public static void main(String[] args) {
        Connection conn = null;

        try {
//JDBC Driver 등록
            Class.forName("com.mysql.cj.jdbc.Driver");

            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/thisisjava",
                    "root",
                    "mysql"
            );

            String sql = ""+
                    "SELECT userid, username, userpassword, userage, useremail "+
                    "FROM users "+
                    "WHERE userid=?";

            PreparedStatement psmt = conn.prepareStatement(sql);
            psmt.setString(1,"winter");

            ResultSet rs = psmt.executeQuery();
            if(rs.next()){
                User user = new User();
                user.setUserId(rs.getString("userid"));
                user.setUserName(rs.getString("username"));
                user.setUserPassword(rs.getString("userpassword"));
                user.setUserAge(rs.getInt(4));
                user.setUserEmail(rs.getString(5));
                System.out.println(user);
            }else{
                System.out.println("사용자 아이디가 존재하지 않음");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if(conn != null) {
                try {
                    //연결 끊기
                    conn.close();
                    System.out.println("연결 끊기");
                } catch (SQLException e) {}
            }
        }
    }
}

SELECT로 데이터를 가져와서 자바 객체로 만드는 코드이다.

트랜잭션 처리

트랜잭션은 기능 처리의 최소 단위를 말한다.
최소 단위란, 소작업들을 분리할 수 없으며 전체를 하나로 본다는 개념이다.
트랜잭션은 소작업들이 모두 성공하거나 모두 실패해야 한다.

예를 들어 계좌 이체는 출금 작업과 입금 과정으로 구성된 트랜잭션이다. 출금과 입금 작업 중 하나만 성공할 순 없으며 모두 성공하거나 모두 실패해야 한다.

//출금 작업
UPDATE accounts SET balance=balance-이체금액 WHERE ano=출금계좌번호

//입금 작업
UPDATE accounts SET balance=balance+이체금액 WHERE ano=입금계좌번호

이 2개의 UPDATE문은 모두 성공하거나 모두 실패해야 한다.
트랜잭션을 위한 일반적인 코드 작성 패턴은 다음과 같다.

Connection conn = null;
try {
		//트랜잭션 시작 ----------------------------------------------------
	 	 //자동 커밋 기능 끄기
 		conn.setAutoCommit(false);
		 //소작업 처리//소작업 처리//커밋 -> 모두 성공 처리
	 	conn.commit();
		//트랜잭션 종료 ----------------------------------------------------
	} catch (Exception e) {
	try {
 		//롤백 -> 모두 실패 처리
		 conn.rollback();
	} catch (SQLException e1) {
	 e1.printStackTraced();
	 finally {
		if(conn != null) {
 			try {
 			//원래대로 자동 커밋 기능 켜기
 			conn.setAutoCommit(true);
			 //연결 끊기
			 conn.close();
		 } catch (SQLException e) {}
	}
}

게시판 구현

package ch20.mysql.sec12;

import java.util.Scanner;

public class BoardExample1 {
    private Scanner sc = new Scanner(System.in);
    public void list(){
        System.out.println("[게시물 목록]");
        System.out.println("-------------------------------------------------------");
        System.out.printf("%-6s%-12s%-16s%-40s\n", "no","writer","date","title");
        System.out.println("-------------------------------------------------------");
        System.out.printf("%-6s%-12s%-16s%-40s \n",
                "1","winter","2022.01.27","게시판에 오신 것을 환영합니다.");
        System.out.printf("%-6s%-12s%-16s%-40s \n",
                "2","winter","2022.01.27","올 겨울은 몹시 춥다.");
        mainMenu();
    }
    public void mainMenu(){
        System.out.println("------------------------------------------------------");
        System.out.println("메인 메뉴: 1.Create | 2.Read | 3.Clear | 4.Exit");
        System.out.print("메뉴 선택: ");
        System.out.println("");
        String sel = sc.nextLine();
        switch (sel){
            case "1" -> create();
            case "2" -> read();
            case "3" -> clear();
            case "4" -> exit();
        }
    }

    private void exit() {
        System.out.println("***exit() 실행됨***");
        list();
    }

    private void clear() {
        System.out.println("***clear() 실행됨***");
        list();
    }

    private void read() {
        System.out.println("***read() 실행됨***");
        list();
    }

    private void create() {
        System.out.println("***create() 실행됨***");
        list();
    }

    public static void main(String[] args) {
        BoardExample1 boardExample1 = new BoardExample1();
        boardExample1.list();
    }
}

기본적인 뼈대를 만들어 준다.

package ch20.mysql.sec12;

import java.sql.*;
import java.util.Scanner;

public class BoardExample3 {
    private Scanner sc = new Scanner(System.in);
    private Connection conn;

    public BoardExample3(){
        try {
//JDBC Driver 등록
            Class.forName("com.mysql.cj.jdbc.Driver");

            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/thisisjava",
                    "root",
                    "mysql"
            );

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } 
    }
    public void list(){
        System.out.println("[NEW 게시물 목록]");
        System.out.println("-------------------------------------------------------");
        System.out.printf("%-6s%-12s%-16s%-40s\n", "no","writer","date","title");
        System.out.println("-------------------------------------------------------");
        try{
            String sql = ""+
                    "SELECT bno, btitle, bcontent, bwriter, bdate "+
                    "FROM boards "+
                    "ORDER BY bno DESC";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery();
            while (rs.next()){
                Board board = new Board();
                board.setBno(rs.getInt("bno"));
                board.setBtitle(rs.getString("btitle"));
                board.setBcontent(rs.getString("bcontent"));
                board.setBwriter(rs.getString("bwriter"));
                board.setBdate(rs.getDate("bdate"));
                System.out.printf("%-6s%-12s%-16s%-40s \n",
                        board.getBno(),
                        board.getBwriter(),
                        board.getBdate(),
                        board.getBtitle());
            }
            rs.close();
            pstmt.close();
        }catch(SQLException e){
            e.printStackTrace();
        }
        mainMenu();
    }
    public void mainMenu(){
        System.out.println("------------------------------------------------------");
        System.out.println("메인 메뉴: 1.Create | 2.Read | 3.Clear | 4.Exit");
        System.out.print("메뉴 선택: ");
        System.out.println("");
        String sel = sc.nextLine();
        switch (sel){
            case "1" -> create();
            case "2" -> read();
            case "3" -> clear();
            case "4" -> exit();
        }
    }

    private void exit() {
        System.out.println("***exit() 실행됨***");
        list();
    }

    private void clear() {
        System.out.println("***clear() 실행됨***");
        list();
    }

    private void read() {
        System.out.println("***read() 실행됨***");
        list();
    }

    private void create() {
        System.out.println("***create() 실행됨***");
        list();
    }

    public static void main(String[] args) {
        BoardExample3 boardExample3 = new BoardExample3();
        boardExample3.list();
    }
}

그 다음 DB를 연결해 주고 게시글 출력 부분을 DB에서 가져오는 걸로 바꿔준다.

 private void create() {
        Board board = new Board();
        System.out.println("[새 게시물 입력]");
        System.out.print("제목: ");
        board.setBtitle(sc.nextLine());
        System.out.print("내용: ");
        board.setBcontent(sc.nextLine());
        System.out.print("작성자: ");
        board.setBwriter(sc.nextLine());

        System.out.println("------------------------------------------------------");
        System.out.println("보조 메뉴 : 1. OK | 2. Cancel");
        System.out.print("메뉴 선택 : ");
        String menuNo = sc.nextLine();
        if(menuNo.equals("1")){
            try{
                String sql = ""+
                        "INSERT INTO boards (btitle, bcontent, bwriter, bdate) " +
                        "VALUES (?, ?, ?, now())";
                PreparedStatement psmt = conn.prepareStatement(sql);
                psmt.setString(1,board.getBtitle());
                psmt.setString(2,board.getBcontent());
                psmt.setString(3,board.getBwriter());
                psmt.executeUpdate();
                psmt.close();
            }catch(Exception e){
                
            }
        }
        list();
    }

글 쓰기 메소드를 완성해 준다.

 private void read() {
        System.out.println("[게시물 읽기]");
        System.out.print("bno: ");
        int bno = Integer.parseInt(sc.nextLine());
        try{
            String sql = "" +
                     "SELECT bno, btitle, bcontent, bwriter, bdate " +
                     "FROM boards " +
                     "WHERE bno= ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, bno);
             ResultSet rs = pstmt.executeQuery();
            if(rs.next()) {
                 Board board = new Board();
                 board.setBno(rs.getInt("bno"));
                 board.setBtitle(rs.getString("btitle"));
                 board.setBcontent(rs.getString("bcontent"));
                 board.setBwriter(rs.getString("bwriter"));
                 board.setBdate(rs.getDate("bdate"));
                 System.out.println("#############");
                 System.out.println("번호: " + board.getBno());
                 System.out.println("제목: " + board.getBtitle());
                 System.out.println("내용: " + board.getBcontent());
                 System.out.println("작성자: " + board.getBwriter());
                 System.out.println("날짜: " + board.getBdate());
                 System.out.println("#############");
                 System.out.println("----------------------");
                 System.out.println("보조 메뉴 : 1.Update | 2.Delete | 3.List");
                 System.out.print("메뉴 선택");
                 String menuNo = sc.nextLine();
                if (menuNo.equals("1")) {
                    update(board);
                }else if(menuNo.equals("2")){
                    delete(board);
                }else{

                }
            }
             rs.close();
             pstmt.close();
            }    catch(Exception e){}
        list();
    }
    private void delete(Board board){
        try{
            String sql = "DELETE FROM boards WHERE bno=?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1,board.getBno());
            pstmt.executeUpdate();
            pstmt.close();
        }catch(Exception e){
            exit();
        }
        list();
    }
    private void update(Board board) {

        System.out.println("[수정 내용 입력]");
         System.out.print("제목: ");
         board.setBtitle(sc.nextLine());
         System.out.print("내용: ");
         board.setBcontent(sc.nextLine());
         System.out.print("작성자: ");
         board.setBwriter(sc.nextLine());

         //보조 메뉴 출력
         System.out.println("------------------------------------------------------");
         System.out.println("보조 메뉴: 1.Ok | 2.Cancel");
         System.out.print("메뉴 선택: ");
         String menuNo = sc.nextLine();
         if(menuNo.equals("1")) {

            try {
                String sql = "" +
                         "UPDATE boards SET btitle= ?, bcontent= ?, bwriter= ? " +
                         "WHERE bno= ?";
                 PreparedStatement pstmt = conn.prepareStatement(sql);
                 pstmt.setString(1, board.getBtitle());
                 pstmt.setString(2, board.getBcontent());
                 pstmt.setString(3, board.getBwriter());
                 pstmt.setInt(4, board.getBno());
                 pstmt.executeUpdate();
                 pstmt.close();
            } catch (Exception e) {
                 e.printStackTrace();
                 exit();
                 }
             }
         list();
    }

게시글 번호를 누르면 해당 게시글의 내용을 읽을 수 있게 만들어 준다.
또한 게시글을 읽었을 때 해당 게시글을 수정하거나 삭제하는 기능도 넣어 준다.

 private void clear() {
        System.out.println("[게시물 전체 삭제]");
        System.out.println("-------------------------------------------------------");
        System.out.println("보조 메뉴: 1.Ok | 2.Cancel");
        System.out.print("메뉴 선택: ");
        String menuNo = sc.nextLine();
        if(menuNo.equals("1")) {
             try {
                 String sql = "TRUNCATE TABLE boards";
                 PreparedStatement pstmt = conn.prepareStatement(sql);
                 pstmt.executeUpdate();
                 pstmt.close();
                 } catch (Exception e) {
                 e.printStackTrace();
                 exit();
                 }
             }
        list();
    }

    private void exit() {
        if(conn != null){
            try{
                conn.close();
            }catch(SQLException e){

            }
        }
        System.out.println("** 게시판 종료 **");
        System.exit(0);
    }

나머지 clear()와 exit()를 구현해 주면 게시판 완성이다.

연습문제

4번

3번 테이블 이름은 조회해서 보면 됩니다.

2->1->4->3


4번, 1번 부터 시작합니다.

2번 afterLast가 되면 false가 리턴됩니다.

3번


3번, 내부 작업은 모두 통일된 상태여야 합니다.

private void join() {
        User user = new User();
        System.out.println("[새로운 사용자 등록]");
        System.out.print("아이디: ");
        user.setUserId(sc.nextLine());
        System.out.print("이름: ");
        user.setUserName(sc.nextLine());
        System.out.print("비밀번호: ");
        user.setUserPassword(sc.nextLine());
        System.out.println("나이: ");
        user.setUserAge(Integer.parseInt(sc.nextLine()));
        System.out.println("이메일: ");
        user.setUserEmail(sc.nextLine());
        System.out.println("------------------------------------------------------");
        System.out.println("보조 메뉴 : 1. OK | 2. Cancel");
        System.out.print("메뉴 선택 : ");
        String menuNo = sc.nextLine();
        if(menuNo.equals("1")){
            try{
                String sql = "" +
                        "INSERT INTO users (userid, username, userpassword, userage, useremail) " +
                        "VALUES (?, ?, ?, ?, ?)";
                PreparedStatement pstmt = conn.prepareStatement(sql);
                pstmt.setString(1,user.getUserId());
                pstmt.setString(2, user.getUserName());
                pstmt.setString(3, user.getUserPassword());
                pstmt.setInt(4, user.getUserAge());
                pstmt.setString(5, user.getUserEmail());
                pstmt.executeUpdate();
                pstmt.close();
            }catch(Exception e){

            }
        }
        list();
    }

앞서 만든 게시판 소스에서 조금만 수정해 주면 되는데, sql 쿼리문을 게시판이 아니라 사용자에 대한 걸로 해서 추가하면 됩니다. User.java도 새로 만들고.. 로그인 세션을 담는 boolean도 깨작 선언해 준다음에

package ch20.mysql.sec12;

import java.sql.*;
import java.util.Scanner;

public class BoardExample3 {
    private Scanner sc = new Scanner(System.in);
    private Connection conn;
    private String name = "";
    private boolean session = false;

    public BoardExample3(){
        try {
//JDBC Driver 등록
            Class.forName("com.mysql.cj.jdbc.Driver");

            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/thisisjava",
                    "root",
                    "mysql"
            );

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void list(){
        if(session)  System.out.println("[게시물 목록] 사용자 :"+name);
        else System.out.println("[게시물 목록]");
        System.out.println("-------------------------------------------------------");
        System.out.printf("%-6s%-12s%-16s%-40s\n", "no","writer","date","title");
        System.out.println("-------------------------------------------------------");
        try{
            String sql = ""+
                    "SELECT bno, btitle, bcontent, bwriter, bdate "+
                    "FROM boards "+
                    "ORDER BY bno DESC";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery();
            while (rs.next()){
                Board board = new Board();
                board.setBno(rs.getInt("bno"));
                board.setBtitle(rs.getString("btitle"));
                board.setBcontent(rs.getString("bcontent"));
                board.setBwriter(rs.getString("bwriter"));
                board.setBdate(rs.getDate("bdate"));
                System.out.printf("%-6s%-12s%-16s%-40s \n",
                        board.getBno(),
                        board.getBwriter(),
                        board.getBdate(),
                        board.getBtitle());
            }
            rs.close();
            pstmt.close();
        }catch(SQLException e){
            e.printStackTrace();
        }
        mainMenu();
    }
    public void mainMenu(){
        System.out.println("------------------------------------------------------");
        if(session) System.out.println("메인 메뉴: 1.Create | 2.Read | 3.Clear | 4.Join | 5.LogOut | 6.Exit ");
        else System.out.println("메인 메뉴: 1.Create | 2.Read | 3.Clear | 4.Join | 5.Login | 6.Exit ");
        System.out.print("메뉴 선택: ");
        System.out.println("");
        String sel = sc.nextLine();
        switch (sel){
            case "1" -> create();
            case "2" -> read();
            case "3" -> clear();
            case "4" -> join();
            case "5" -> {

                if(!session)login();
                else{
                    session = false;
                    name = "";
                    list();
                }

            }
            case "6" -> exit();
        }
    }

    private void join() {
        User user = new User();
        System.out.println("[새로운 사용자 등록]");
        System.out.print("아이디: ");
        user.setUserId(sc.nextLine());
        System.out.print("이름: ");
        user.setUserName(sc.nextLine());
        System.out.print("비밀번호: ");
        user.setUserPassword(sc.nextLine());
        System.out.println("나이: ");
        user.setUserAge(Integer.parseInt(sc.nextLine()));
        System.out.println("이메일: ");
        user.setUserEmail(sc.nextLine());
        System.out.println("------------------------------------------------------");
        System.out.println("보조 메뉴 : 1. OK | 2. Cancel");
        System.out.print("메뉴 선택 : ");
        String menuNo = sc.nextLine();
        if(menuNo.equals("1")){
            try{
                String sql = "" +
                        "INSERT INTO users (userid, username, userpassword, userage, useremail) " +
                        "VALUES (?, ?, ?, ?, ?)";
                PreparedStatement pstmt = conn.prepareStatement(sql);
                pstmt.setString(1,user.getUserId());
                pstmt.setString(2, user.getUserName());
                pstmt.setString(3, user.getUserPassword());
                pstmt.setInt(4, user.getUserAge());
                pstmt.setString(5, user.getUserEmail());
                pstmt.executeUpdate();
                pstmt.close();
            }catch(Exception e){

            }
        }
        list();
    }

    private void login() {
        String id = "";
        String pwd = "";
        System.out.println("[로그인]");
        System.out.print("아이디: ");
        id = sc.nextLine();
        System.out.print("비밀번호: ");
        pwd = sc.nextLine();
        System.out.println("------------------------------------------------------");
        System.out.println("보조 메뉴 : 1. OK | 2. Cancel");
        System.out.print("메뉴 선택 : ");
        String menuNo = sc.nextLine();
        if(menuNo.equals("1")){
            try{
                String sql = ""+
                        "SELECT userid, username, userpassword, userage, useremail "+
                        "FROM users "+
                        "WHERE userid=?";

                PreparedStatement psmt = conn.prepareStatement(sql);
                psmt.setString(1,id);

                ResultSet rs = psmt.executeQuery();
                if(rs.next()){
                    if(id.equals(rs.getString("userid")) && pwd.equals(rs.getString("userpassword"))){
                        session = true;
                        name = rs.getString("username");
                        list();
                    }
                }else{
                    System.out.println("아이디가 존재하지 않습니다.");
                    join();
                }
            }catch(Exception e){

            }
        }
        list();

    }

    private void clear() {
        System.out.println("[게시물 전체 삭제]");
        System.out.println("-------------------------------------------------------");
        System.out.println("보조 메뉴: 1.Ok | 2.Cancel");
        System.out.print("메뉴 선택: ");
        String menuNo = sc.nextLine();
        if(menuNo.equals("1")) {
             try {
                 String sql = "TRUNCATE TABLE boards";
                 PreparedStatement pstmt = conn.prepareStatement(sql);
                 pstmt.executeUpdate();
                 pstmt.close();
                 } catch (Exception e) {
                 e.printStackTrace();
                 exit();
                 }
             }
        list();
    }

    private void exit() {
        if(conn != null){
            try{
                conn.close();
            }catch(SQLException e){

            }
        }
        System.out.println("** 게시판 종료 **");
        System.exit(0);
    }

    private void read() {
        System.out.println("[게시물 읽기]");
        System.out.print("bno: ");
        int bno = Integer.parseInt(sc.nextLine());
        try{
            String sql = "" +
                     "SELECT bno, btitle, bcontent, bwriter, bdate " +
                     "FROM boards " +
                     "WHERE bno= ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, bno);
             ResultSet rs = pstmt.executeQuery();
            if(rs.next()) {
                 Board board = new Board();
                 board.setBno(rs.getInt("bno"));
                 board.setBtitle(rs.getString("btitle"));
                 board.setBcontent(rs.getString("bcontent"));
                 board.setBwriter(rs.getString("bwriter"));
                 board.setBdate(rs.getDate("bdate"));
                 System.out.println("#############");
                 System.out.println("번호: " + board.getBno());
                 System.out.println("제목: " + board.getBtitle());
                 System.out.println("내용: " + board.getBcontent());
                 System.out.println("작성자: " + board.getBwriter());
                 System.out.println("날짜: " + board.getBdate());
                 System.out.println("#############");
                 System.out.println("----------------------");
                 System.out.println("보조 메뉴 : 1.Update | 2.Delete | 3.List");
                 System.out.print("메뉴 선택");
                 String menuNo = sc.nextLine();
                if (menuNo.equals("1")) {
                    update(board);
                }else if(menuNo.equals("2")){
                    delete(board);
                }else{

                }
            }
             rs.close();
             pstmt.close();
            }    catch(Exception e){}
        list();
    }
    private void delete(Board board){
        try{
            String sql = "DELETE FROM boards WHERE bno=?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1,board.getBno());
            pstmt.executeUpdate();
            pstmt.close();
        }catch(Exception e){
            exit();
        }
        list();
    }
    private void update(Board board) {

        System.out.println("[수정 내용 입력]");
         System.out.print("제목: ");
         board.setBtitle(sc.nextLine());
         System.out.print("내용: ");
         board.setBcontent(sc.nextLine());
         System.out.print("작성자: ");
         board.setBwriter(sc.nextLine());

         //보조 메뉴 출력
         System.out.println("------------------------------------------------------");
         System.out.println("보조 메뉴: 1.Ok | 2.Cancel");
         System.out.print("메뉴 선택: ");
         String menuNo = sc.nextLine();
         if(menuNo.equals("1")) {

            try {
                String sql = "" +
                         "UPDATE boards SET btitle= ?, bcontent= ?, bwriter= ? " +
                         "WHERE bno= ?";
                 PreparedStatement pstmt = conn.prepareStatement(sql);
                 pstmt.setString(1, board.getBtitle());
                 pstmt.setString(2, board.getBcontent());
                 pstmt.setString(3, board.getBwriter());
                 pstmt.setInt(4, board.getBno());
                 pstmt.executeUpdate();
                 pstmt.close();
            } catch (Exception e) {
                 e.printStackTrace();
                 exit();
                 }
             }
         list();
    }
    private void create() {
        Board board = new Board();
        System.out.println("[새 게시물 입력]");
        System.out.print("제목: ");
        board.setBtitle(sc.nextLine());
        System.out.print("내용: ");
        board.setBcontent(sc.nextLine());
        System.out.print("작성자: ");
        board.setBwriter(sc.nextLine());

        System.out.println("------------------------------------------------------");
        System.out.println("보조 메뉴 : 1. OK | 2. Cancel");
        System.out.print("메뉴 선택 : ");
        String menuNo = sc.nextLine();
        if(menuNo.equals("1")){
            try{
                String sql = ""+
                        "INSERT INTO boards (btitle, bcontent, bwriter, bdate) " +
                        "VALUES (?, ?, ?, now())";
                PreparedStatement psmt = conn.prepareStatement(sql);
                psmt.setString(1,board.getBtitle());
                psmt.setString(2,board.getBcontent());
                psmt.setString(3,board.getBwriter());
                psmt.executeUpdate();
                psmt.close();
            }catch(Exception e){

            }
        }
        list();
    }

    public static void main(String[] args) {
        BoardExample3 boardExample3 = new BoardExample3();
        boardExample3.list();
    }
}
profile
gotta go fast
post-custom-banner

0개의 댓글