0410 JDBC 활용 JAVA에서 구현하기

Fifty·2025년 4월 10일

2. JAVA

목록 보기
22/33

회원가입 / 로그인 / 게시글작성 및 조회 프로그램

아래와 같이 기능을 하는 프로그램을 구현한다.

  1. 회원가입 → 메인메뉴
  2. 메인메뉴: 게시글 작성, 게시글 조회
  3. 게시글 작성 → 메인메뉴
  4. 게시글 조회 → 메뉴: 전체조회(전부 다 출력), 선택조회(게시글 번호)

위 내용을 참고해서 메뉴를 아래와 같이 정리한다.

  1. 회원가입
  2. 로그인
  3. 게시글 작성
  4. 게시글 조회
  5. 종료

기본 기능은 구현이 가능하지만 테스트 과정에서 보완사항이 도출되었다.

보완사항

  1. 회원가입 할 때 id가 겹치면 기본값이 충돌나기 때문에 오류가 날 것으로 예상 → 사용자에게 다시 안내
  2. 게시글 작성은 회원인 사람만 가능하도록 로그인 여부를 체크하는 기능과 아이디 가져오게 추가 필요
  3. 게시글 작성 후 조회 간 사용자가 수정하고 싶을 때 수정할 수 있는 기능 추가 필요
  4. 게시글 작성한 작성자가 게시글을 삭제하고 싶을 때 삭제할 수 있는 기능 추가 필요
  5. 기능마다 새로 변수를 선언해서 속도가 너무 느림
  6. 게시글 작성 시 bno를 실행할 때마다 초기화되는 것이 문제 → MAX(bno)를 가져와서 최신화 해주었음!

ChatCPT 검사 결과

잘 된 점

기능분리: AllTest에서 메뉴처리, DB작업은 JDBCTest_Insert와 JDBCTest_Select
객체지향 설계: Member, Board 클래스
입력 처리 로직 직관적: 사용자 입력 흐름이 자연스럽고 친절한 메시지로 사용자 경험 향상

개선사항

SQLInjection 취약 → 쿼리를 문자열로 연결하는 것이 아닌 PreparedStatement로 변경(!)
로그인 후 상태 관리 미흡
리소스 누수 가능ㅇ성: Connection, Statement, ResultSet을 닫지 않고 있어 리소스 누수 발생, close()호출
기능 추가 고려사항: 게시글 수정/삭제, 로그인 상태 유지 및 인증 기반 기능 제한, 게시글 검색, 비밀번호 암호화

회원가입 ~ 로그인

게시글 작성

게시글 조회

DB 조회(Member)

DB 조회(Board)


전체 테스트 JAVA

AllTest.java

package Test;

import java.sql.SQLException;
import java.util.Scanner;

public class AllTest {

	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		// TODO Auto-generated method stub
		/*
		1. 회원가입 → 메인메뉴
		2. 메인메뉴: 게시글 작성, 게시글 조회
		3. 게시글 작성 → 메인메뉴
		4. 게시글 조회 → 메뉴: 전체조회(전부 다 출력), 선택조회(게시글 번호)
		*/
		
		Scanner sc = new Scanner(System.in);
		boolean flag = true;
		
		while(flag) {
			printMenu();
			int input = sc.nextInt();
			if(input==0) {
				break;
			}
			else
				moveMenu(input);
		}
		System.out.println("[안내] 종료하겠습니다.");
		
	}
	
	// 메뉴 출력
	public static void printMenu() {
		System.out.println("====Menu====");
		System.out.println("1. 회원가입");
		System.out.println("2. 로그인");
		System.out.println("3. 게시글 작성");
		System.out.println("4. 게시글 조회");
		System.out.println("------------");
		System.out.println("0. 종료");
		System.out.println("============");
		System.out.print("메뉴 선택 > ");
	}
	
	public static void moveMenu(int input) throws ClassNotFoundException, SQLException {
		switch(input) {
		case 1: joinMember(); break;
		case 2: login(); break;
		case 3: writeBoard(); break;
		case 4: readBoard(); break;
		default: System.out.println("다시 선택해주세요.");
		}
	}
	
	// 회원가입
	public static void joinMember() throws ClassNotFoundException, SQLException {
		JDBCTest_Insert insert = new JDBCTest_Insert();
		insert.insertJoin();
	}
	
	// 로그인
	public static void login() throws ClassNotFoundException, SQLException {
		JDBCTest_Select select = new JDBCTest_Select();
		select.listMember();
		
	}
	
	// 게시글 작성
	public static void writeBoard() throws ClassNotFoundException, SQLException {
		JDBCTest_Insert insert = new JDBCTest_Insert();
		insert.insertBoard();
	}
	
	// 게시글 조회
	public static void readBoard() throws ClassNotFoundException, SQLException {
		
		JDBCTest_Select select = new JDBCTest_Select();
		select.listBoard();
	}

}

Member와 Board 클래스

Member.java

package Test;

public class Member {
	private String id;
	private String pw;
	private String name;
	private String phone;
	private char grade;
	
	
	public String getId() {
		return id;
	}
	public String getPw() {
		return pw;
	}
	public String getName() {
		return name;
	}
	public String getPhone() {
		return phone;
	}
	public char getGrade() {
		return grade;
	}
	public void setId(String id) {
		this.id = id;
	}
	public void setPw(String pw) {
		this.pw = pw;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public void setGrade(char grade) {
		this.grade = grade;
	}
	@Override
	public String toString() {
		return "Member [id=" + id + ", pw=" + pw + ", name=" + name + ", phone=" + phone + ", grade=" + grade + "]";
	}
	
}

Board.java

package Test;

public class Board {
	private int bno;
	private String title;
	private String content;
	private String writer;
	private String regdate;
	public int getBno() {
		return bno;
	}
	public String getTitle() {
		return title;
	}
	public String getContent() {
		return content;
	}
	public String getWriter() {
		return writer;
	}
	public String getRegdate() {
		return regdate;
	}
	public void setBno(int bno) {
		this.bno = bno;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}
	@Override
	public String toString() {
		return "Board [bno=" + bno + ", title=" + title + ", content=" + content + ", writer=" + writer + ", date="
				+ regdate + "]";
	}
		
}

JDBCTest_Select.java

package Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class JDBCTest_Select {

	//public static void main(String[] args) throws ClassNotFoundException, SQLException {
	public static void listMember() throws ClassNotFoundException, SQLException {
		List<Member> list = new ArrayList<>();					// 3. 쿼리 실행 후 회원 정보값을 저장할 리스트
		
		Class.forName("oracle.jdbc.driver.OracleDriver");
		
		/* 1. DB에 접속하기 위한 정보 */
		String url = "jdbc:oracle:thin:@localhost:1521:testdb";  // DB가 설치된 곳에 지정
		String user = "green";
		String password = "1234";

		/* 2. DB에 접속, 접속 성공 시 conn에 반환 */
		Connection conn = DriverManager.getConnection(url, user, password);
		
		/* 3. 쿼리 실행 - Statement */
		Statement stmt = conn.createStatement();
		String query = "SELECT * FROM tbl_member";				// 실행할 쿼리 작성
		ResultSet rs = stmt.executeQuery(query);				// SELECT는 결과값을 받아줘야하고, executeQuery의 자료형은 ResultSet이다.
		

		while(rs.next()) {										// 조회 쿼리시 1개 이상의 컬럼이 나올 걸 예상해서 반복문, next()는 다음 것이 있으면 true
			Member member = new Member();						// 멤버 인스턴스의 위치도 반복문 안으로 설정해줘야 한다.

			String id = rs.getString("id");
			String pw = rs.getString("pw");
			String name = rs.getString("name");
			String phone = rs.getString("phone");
			String grade_temp = rs.getString("grade");			//rs가 char를 제공하지 않아서 String으로
			char grade = grade_temp.charAt(0);
			
			member.setId(id);
			member.setPw(pw);
			member.setName(name);
			member.setPhone(phone);
			member.setGrade(grade);
			
			list.add(member);
		}
		
		/*
		for(Member m : list) {									// ArrayList에 저장된 Member를 출력
			System.out.println(m);
		}
		 */
		checkMember(list);
		
	}
	
	// 회원인지 확인하는 메소드
	public static void checkMember(List<Member> list) {

		boolean flag=false;
		System.out.println("[안내] 로그인 페이지입니다.");
		Scanner sc = new Scanner(System.in);
		System.out.print("ID > ");
		String user_id=sc.next();
		System.out.print("PW > ");
		String user_pw=sc.next();
		
		for(Member m: list) {
			if(user_id.equals(m.getId()) && user_pw.equals(m.getPw())) {
				flag=true;
				System.out.println("[안내] 로그인 성공!");
				break;
			}
			else {
				flag=false;
			}
		}
		if(!flag) System.out.println("[안내] ID와 비밀번호를 다시 확인하세요");
		
		
	}

	
	public static void listBoard() throws ClassNotFoundException, SQLException {
		List<Board> boardList = new ArrayList<>();					// 3. 쿼리 실행 후 회원 정보값을 저장할 리스트
		
		Class.forName("oracle.jdbc.driver.OracleDriver");
		
		/* 1. DB에 접속하기 위한 정보 */
		String url = "jdbc:oracle:thin:@localhost:1521:testdb";  // DB가 설치된 곳에 지정
		String user = "green";
		String password = "1234";

		/* 2. DB에 접속, 접속 성공 시 conn에 반환 */
		Connection conn = DriverManager.getConnection(url, user, password);
		
		/* 3. 쿼리 실행 - Statement */
		Statement stmt = conn.createStatement();
		String query = "SELECT * FROM tbl_board";				// 실행할 쿼리 작성
		ResultSet rs = stmt.executeQuery(query);				// SELECT는 결과값을 받아줘야하고, executeQuery의 자료형은 ResultSet이다.

		while(rs.next()) {										// 조회 쿼리시 1개 이상의 컬럼이 나올 걸 예상해서 반복문, next()는 다음 것이 있으면 true
			Board board = new Board();						// 멤버 인스턴스의 위치도 반복문 안으로 설정해줘야 한다.

			
			String bno_temp= rs.getString("bno");
			int bno = Integer.parseInt(bno_temp);
			String title = rs.getString("title");
			String content = rs.getString("content");
			String writer = rs.getString("writer");
			String regdate = rs.getString("regdate");
			
			board.setBno(bno);
			board.setTitle(title);
			board.setContent(content);
			board.setWriter(writer);
			board.setRegdate(regdate);
			
			boardList.add(board);
		}
		
		readBoard(boardList);
		
	}
	public static void readBoard(List<Board> boardList) {
		Scanner sc = new Scanner(System.in);
		System.out.println("[안내] 게시글 조회 페이지입니다.");
		System.out.print("전체조회: 1 | 선택조회: 2 >");
		int choice = sc.nextInt();
		int choicebno;
		switch(choice) {
		case 1: System.out.println("모든 게시글을 조회하겠습니다.");
				for(Board b: boardList)
					System.out.println(b);
				break;
		case 2: System.out.print("몇 번 게시글을 조회하겠습니까? > ");
				choicebno = sc.nextInt();
				System.out.println(choice+"번 게시글 입니다.");
				for(Board b: boardList) {
					if(choicebno==b.getBno())
						System.out.println(b);
				}
		}
	}
}

JDBCTest_Insert.java

package Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCTest_Insert {

	static int board_no;
	//public static void main(String[] args) throws ClassNotFoundException, SQLException {
		// TODO Auto-generated method stub
		//public void insertJoin(String user_id, String user_pw, String user_name, String user_phone) throws ClassNotFoundException, SQLException {
	public void insertJoin() throws ClassNotFoundException, SQLException {
		
		// 회원가입 정보 획득
		Scanner sc = new Scanner(System.in);
		System.out.println("[안내] 회원가입 페이지입니다.");
		System.out.print("아이디 > ");
		String user_id = sc.next();
		System.out.print("비밀번호 > ");
		String user_pw = sc.next();
		System.out.print("이름 > ");
		String user_name = sc.next();
		System.out.print("전화번호 > ");
		String user_phone = sc.next();
		
		
		Class.forName("oracle.jdbc.driver.OracleDriver");
		/* 1. DB에 접속하기 위한 정보 */
		String url="jdbc:oracle:thin:@localhost:1521:testdb";
		String user="green";
		String password="1234";
		/* 2. DB에 접속 */
		Connection conn = DriverManager.getConnection(url, user, password);
		/* 3. 쿼리 실행 */
		Statement stmt = conn.createStatement();
		
		String query = "INSERT INTO tbl_member VALUES('"+user_id+"','"+
		user_pw+"','"+user_name+"','"+user_phone+"','B')";
		
		//System.out.println(query);
		int result = stmt.executeUpdate(query);	// Insert는 삽입 성공 여부가 나온다.
		
		if(result==1)
			System.out.println("새로운 회원이 되신 것을 환영합니다.");
		else
			System.out.println("회원가입 정보를 다시 입력하세요.");
	}
	
	public void insertBoard() throws ClassNotFoundException, SQLException {

		// 게시글 정보 획득
		Scanner sc = new Scanner(System.in);
		System.out.println("[안내] 게시글 작성 페이지입니다.");
		System.out.print("ID > ");
		String user_id = sc.next();
		System.out.print("제목 > ");
		String title = sc.next();
		System.out.print("내용 > ");
		String content = sc.next();
		
		
		Class.forName("oracle.jdbc.driver.OracleDriver");
		/* 1. DB에 접속하기 위한 정보 */
		String url="jdbc:oracle:thin:@localhost:1521:testdb";
		String user="green";
		String password="1234";
		/* 2. DB에 접속 */
		Connection conn = DriverManager.getConnection(url, user, password);
		/* 3. 쿼리 실행 */
		Statement stmt = conn.createStatement();
		
		// Board MAX(bno) 가져오기
		String bnoQuery = "SELECT MAX(bno) FROM tbl_board";
		ResultSet rs = stmt.executeQuery(bnoQuery);
		rs.next();
		String bnoMax = rs.getString("MAX(bno)");
		board_no = Integer.parseInt(bnoMax);
		
		
		String query = "INSERT INTO tbl_board VALUES('"+(++board_no)+"','"+title+"','"+content+"','"+user_id+"',SYSDATE)";
		
		//System.out.println(query);
		
		int result = stmt.executeUpdate(query);
		if(result==1)
			System.out.println("게시글 작성이 완료되었습니다.");
		else
			System.out.println("게시글 작성을 실패했습니다.");
		
	}

}

JDBCTest_Update.java

package Test;

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

public class JDBCTest_Update {

	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		// TODO Auto-generated method stub

		Class.forName("oracle.jdbc.driver.OracleDriver");
		
		/* 1. DB에 접속하기 위한 정보 */
		String url="jdbc:oracle:thin:@localhost:1521:testdb";
		String id="green";
		String password="1234";
		
		/* 2. DB에 접속 */
		Connection conn = DriverManager.getConnection(url	, id, password);
		
		/* 3. 쿼리 실행 */
		Statement stmt = conn.createStatement();
		String query = "UPDATE tbl_member SET phone='010-2222-6666' WHERE name='Amy'";
		
		int result = stmt.executeUpdate(query);
		System.out.println(result);
		
	}

}

JDBCTest_Delete.java

package Test;

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

public class JDBCTest_Delete {

	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		// TODO Auto-generated method stub

		Class.forName("oracle.jdbc.driver.OracleDriver");
		
		/* 1. DB에 접속하기 위한 정보 */
		String url="jdbc:oracle:thin:@localhost:1521:testdb";
		String id="green";
		String password="1234";
		
		/* 2. DB에 접속 */
		Connection conn = DriverManager.getConnection(url, id, password);
		
		/* 3. 쿼리 실행 */
		Statement stmt = conn.createStatement();
		String query = "DELETE FROM tbl_member WHERE name = 'emily'";
		
		int result = stmt.executeUpdate(query);
		System.out.println(result);
	}

}

0개의 댓글