Coding History

국비 지원 IT(웹앱개발) 취업반 강의 23일차 (JDBC)

BlackBirdIT 2024. 7. 8. 17:35

새로 프로젝트를 만들어서 article write와 article list 까지 구현하게 시키셨다.

이후 myspl과 내 프로젝트를 연결했다. 내가 사용하고 있는 것은 인텔리제이이고 여기에 DB를 연결하는 것 까지는 성공했는데, 이후 코드로 연결시켜서 사용하는데에는 계속해서 실패했다.

강사님이 초기 세팅을 알려주셔서 이렇게 일단 연결은 했다,

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

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

        try {
            Class.forName("org.mariadb.jdbc.Driver");
            String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
            conn = DriverManager.getConnection(url, "root", "1234");
            System.out.println("연결 성공!");

        } catch (ClassNotFoundException e) {
            System.out.println("드라이버 로딩 실패" + e);
        } catch (SQLException e) {
            System.out.println("에러 : " + e);
        } finally {
            try {
                if (conn != null && !conn.isClosed()) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}
// build.gradle
dependencies {
    testImplementation platform('org.junit:junit-bom:5.10.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'

    implementation 'org.mariadb.jdbc:mariadb-java-client:2.7.12'
}
DROP DATABASE IF EXISTS `AM_JDBC_2024_07`;
CREATE DATABASE `AM_JDBC_2024_07`;
USE `AM_JDBC_2024_07`;

SHOW TABLES;

이후 INSERT가 테스트를 위해서 JDBCInsertTest 클래스를 만들었다.

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

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

        try {
            Class.forName("org.mariadb.jdbc.Driver");
            String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
            conn = DriverManager.getConnection(url, "root", "1234");
            System.out.println("연결 성공!");

            String sql = "INSERT INTO article\n" +
                    "    SET regDate = now(),\n" +
                    "        updateDate = now(),\n" +
                    "        title = CONCAT('제목1', SUBSTRING(RAND() * 1000 From 1 For 2)),\n" +
                    "        `body` = CONCAT('내용', SUBSTRING(RAND() * 1000 From 1 For 2));";



        } catch (ClassNotFoundException e) {
            System.out.println("드라이버 로딩 실패" + e);
        } catch (SQLException e) {
            System.out.println("에러 : " + e);
        } finally {
            try {
                if (conn != null && !conn.isClosed()) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

강사님은 PreparedStatement pstmt;를 검색해보라고 하셨다.

이걸 사용해서 인서트 테스트를 통과했다.

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

        try {
            Class.forName("org.mariadb.jdbc.Driver");
            String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
            conn = DriverManager.getConnection(url, "root", "1234");
            System.out.println("연결 성공!");

            String sql = "INSERT INTO article\n" +
                    "    SET regDate = now(),\n" +
                    "        updateDate = now(),\n" +
                    "        title = CONCAT('제목1', SUBSTRING(RAND() * 1000 From 1 For 2)),\n" +
                    "        `body` = CONCAT('내용', SUBSTRING(RAND() * 1000 From 1 For 2));";

            pstmt = conn.prepareStatement(sql);

            int affectedRows = pstmt.executeUpdate(); //무슨열에 적용되었는지 알아내는 코드

            System.out.println("affectedRows " + affectedRows);

        } catch (ClassNotFoundException e) {
            System.out.println("드라이버 로딩 실패" + e);
        } catch (SQLException e) {
            System.out.println("에러 : " + e);
        } finally {
            try {
                if (conn != null && !conn.isClosed()) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (pstmt != null && !pstmt.isClosed()) {
                    pstmt.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

이제 doWrite 메서드에 적용만 시키면 되는데,

import java.sql.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class App {
    static Scanner sc;
    static int lastId;
    static List<Article> articles;
    static Connection conn = null;
    static PreparedStatement pstmt = null;


    public App() {
        sc = new Scanner(System.in);
        lastId = 1;
        articles = new ArrayList<>();
    }

    public static void run() throws SQLException {
        System.out.println("== 프로그램 시작 ==");

        while (true) {
            System.out.print("명령어 : ");
            String cmd = sc.nextLine().trim();

            if (cmd.equals("exit")) {
                System.out.println("== 프로그램 종료 ==");
                return;
            } else if (cmd.isEmpty()) {
                System.out.println("명령어 입력해");
            }

            switch (cmd) {
                case "article write":
                    doWrite();
                    break;
                case "article list":
                    showList();
                    break;
//                case "article delete":
//                    doDelete();
//                    break;
                default:
                    System.out.println("명령어오류");
                    break;
            }
        }
    }


    private static void doWrite() {
//        System.out.println("== 게시물 작성 ==");
//        System.out.print("제목 : ");
//        String title = sc.nextLine();
//        System.out.print("내용 : ");
//        String body = sc.nextLine();

        Connection conn = null; // DB 접속하는 객체
        Statement stmt = null; // SQL 전송하는 객체
        ResultSet rs = null; // 결과 받아오는 객체

        String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
        String user = "root";
        String pass = "1234";

        try {
            // 1. 드라이버 세팅
            Class.forName("org.mariadb.jdbc.Driver");

            // 2. Connection 획득
            conn = DriverManager.getConnection(url, user, pass);

            //3. Statement 생성
            stmt = conn.createStatement();

            System.out.print("제목 : ");
            String title = sc.nextLine();
            System.out.print("내용 : ");
            String body = sc.nextLine();

            //4. SQL 처리하고 결과 ResultSet에 받아오기
            String sql = "INSERT INTO article SET title = '" + title + "', body = '" + body + "'";
            stmt.executeUpdate(sql);
            System.out.println("게시물 등록이 완료되었습니다.");
            // 조회 결과 있는 거 -> executeQuery(sql);
            // 조회 결과 없는 거 -> executeUpdate(sql);

        } catch (Exception e) {
            System.out.println("접속 시도중 문제 발생!!");
        }

//        articles.add(new Article(id, title, body));
    }

//    private static Connection getConnection() throws SQLException, ClassNotFoundException {
//        Class.forName("org.mariadb.jdbc.Driver");
//        String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
//        String user = "root";
//        String password = "1234"; // 자신의 MySQL 비밀번호로 변경
//        return DriverManager.getConnection(url, user, password);
//    }

    private static void showList() {
        // board db의 article table에서 데이터를 꺼내와 출력

        // 자동임포트 : alt + enter
        Connection conn = null; // DB 접속하는 객체
        Statement stmt = null; // SQL 전송하는 객체
        ResultSet rs = null; // 결과 받아오는 객체

        String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
        String user = "root";
        String pass = "1234";


        try {
            // 1. 드라이버 세팅
            Class.forName("org.mariadb.jdbc.Driver");

            // 2. Connection 획득
            conn = DriverManager.getConnection(url, user, pass);

            //3. Statement 생성
            stmt = conn.createStatement();
            //4. SQL 처리하고 결과 ResultSet에 받아오기
            String sql = "SELECT * FROM article";
            rs = stmt.executeQuery(sql);

            while (rs.next()) {
                System.out.println(rs.getInt("id"));
                System.out.println(rs.getString("title"));
                System.out.println(rs.getString("body")); // 문자열로 리턴
                System.out.println("========================");
            }

        } catch (Exception e) {
            System.out.println("접속 오류");
        }
    }
}

일단 구글링으로 어떻게 해서 만들었다. 이게 왜 되는건지 잘 이해가 안되는데 이걸 써야지 DB에서 데이터를 가져올 수 있고, 이걸 써야지 DB에 데이터를 저장할 수 있다고 생각하면 조금 더 쉬울 것 같다. 강사님도 그렇게 말씀하셨다.

여튼 겹치는 부분들이 보여서 전역 변수로 바꿔 정리도 조금 해 보았다.

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

public class App {
    static Scanner sc;


    static Connection conn = null; // DB 접속하는 객체
    static Statement stmt = null; // SQL 전송하는 객체
    static ResultSet rs = null; // 결과 받아오는 객체


    public App() {
        sc = new Scanner(System.in);
        conn = null;
        stmt = null;
        rs = null;
    }

    public static void run() throws SQLException {
        System.out.println("== 프로그램 시작 ==");

        while (true) {
            System.out.print("명령어 : ");
            String cmd = sc.nextLine().trim();

            if (cmd.equals("exit")) {
                System.out.println("== 프로그램 종료 ==");
                return;
            } else if (cmd.isEmpty()) {
                System.out.println("명령어 입력해");
            }

            switch (cmd) {
                case "article write":
                    doWrite();
                    break;
                case "article list":
                    showList();
                    break;
//                case "article delete":
//                    doDelete();
//                    break;
                default:
                    System.out.println("명령어오류");
                    break;
            }
        }
    }


    private static void doWrite() {
//        System.out.println("== 게시물 작성 ==");
//        System.out.print("제목 : ");
//        String title = sc.nextLine();
//        System.out.print("내용 : ");
//        String body = sc.nextLine();



        String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
        String user = "root";
        String pass = "1234";

        try {
            // 1. 드라이버 세팅
            Class.forName("org.mariadb.jdbc.Driver");

            // 2. Connection 획득
            conn = DriverManager.getConnection(url, user, pass);

            //3. Statement 생성
            stmt = conn.createStatement();

            System.out.print("제목 : ");
            String title = sc.nextLine();
            System.out.print("내용 : ");
            String body = sc.nextLine();

            //4. SQL 처리하고 결과 ResultSet에 받아오기
            String sql = "INSERT INTO article SET title = '" + title + "', body = '" + body + "'";
            stmt.executeUpdate(sql);
            System.out.println("게시물 등록이 완료되었습니다.");
            // 조회 결과 있는 거 -> executeQuery(sql);
            // 조회 결과 없는 거 -> executeUpdate(sql);

        } catch (Exception e) {
            System.out.println("접속 시도중 문제 발생!!");
        }

//        articles.add(new Article(id, title, body));
    }

    private static void showList() {
        // board db의 article table에서 데이터를 꺼내와 출력

        // 자동임포트 : alt + enter

        String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
        String user = "root";
        String pass = "1234";


        try {
            // 1. 드라이버 세팅
            Class.forName("org.mariadb.jdbc.Driver");

            // 2. Connection 획득
            conn = DriverManager.getConnection(url, user, pass);

            //3. Statement 생성
            stmt = conn.createStatement();
            //4. SQL 처리하고 결과 ResultSet에 받아오기
            String sql = "SELECT * FROM article";
            rs = stmt.executeQuery(sql);

            while (rs.next()) {
                System.out.println(rs.getInt("id"));
                System.out.println(rs.getString("title"));
                System.out.println(rs.getString("body")); // 문자열로 리턴
                System.out.println("========================");
            }

        } catch (Exception e) {
            System.out.println("접속 오류");
        }
    }
}

아 강사님 말씀에 테스트를 해보고 그대로 복붙해오면 쉳다고 말씀하셨다. 강사님이 가이드를 주신 것이다. 그래서 내친김에 다 했지만 select테스트도 만들어봤다,

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

        try {
            Class.forName("org.mariadb.jdbc.Driver");
            String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
            conn = DriverManager.getConnection(url, "root", "1234");
            System.out.println("연결 성공!");

            pstmt = conn.createStatement();
            //4. SQL 처리하고 결과 ResultSet에 받아오기
            String sql = "SELECT * FROM article";
            ResultSet rs = pstmt.executeQuery(sql);
            while (rs.next()) {
                System.out.println(rs.getInt("id"));
                System.out.println(rs.getString("title"));
                System.out.println(rs.getString("body"));
                System.out.println(rs.getString("regDate"));
                System.out.println("=".repeat(50));
            }

        } catch (ClassNotFoundException e) {
            System.out.println("드라이버 로딩 실패" + e);
        } catch (SQLException e) {
            System.out.println("에러 : " + e);
        } finally {
            try {
                if (conn != null && !conn.isClosed()) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (pstmt != null && !pstmt.isClosed()) {
                    pstmt.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

아무리 봐도 맞게한 것 같은데 계속 콘솔에 아무것도 안떠서 잘 생각해보니까 내가 뭐 수정한다고 DB를 비워서 그랬다.

여하튼 점점 더 머리가 아파짐과 동시에 좀 재미도 있는 것 같다. 뭔가 하나하나 쌓아갈 때 마다 묘한 기분이 든다.

아무튼 decs를 사용해서 id로 역순 정렬까지 하고, 수업은 마무리 되었다. list 구현까지는 꼭 해보고 오라고 하셨고 (필자는 어떻게 하긴했다.) 오늘 원래는 시험인데 한명이 출석을 하지 않아 내일로 미뤄져서 오늘은 마치고 article 한번 더 반복하고 집에 가려고 한다.