수달이네 기술 블로그

4. JDBC기능 구현 + SEQUENCE문 본문

RDBMS

4. JDBC기능 구현 + SEQUENCE문

슬픈 수달이 2025. 10. 30. 23:49

SEQUENCE(순서대로 값을 넣어줌)

CREATE SEQUENCE SEQ_USER_NO
START WITH 2
INCREMENT BY 1
NOCACHE
NOCYCLE;

  • SEQ_USER_NO: 시퀀스 이름
  • START WITH 2: 2부터 시작
  • INCREMENT BY 1: 호출할 때 마다 1씩증가
  • NOCACHE: 미리 값을 캐시에 저장하지 않아 DB가 종료되더라도 번호가 건너뛰어지지 않음
  • NOCYCLE: 최대값에 도달해도 처음으로 돌아가지 않음.
INSERT INTO TBL_USER
VALUES(SEQ_USER_NO.NEXTVAL, 'test2', '1234', '홍길동', 20, 'M');
  • VALUES의 값에서 넣고 싶은 곳에 SEQUENCE를 넣어 사용한다.
SELECT SEQ_USER_NO.CURRVAL
FROM DUAL;

위와 같이 DUAL테이블에서 현재 시퀀스값을 확인 할 수 있다.

  • CURRVAL: 현재 시퀀스 값
  • NEXTVAL: 다음 시퀀스 값 (만약 시퀀스 값을 이걸로 확인할 경우 값이 하나 늘어버림)
    • 무조건 다음 값으로 넘겨버리는 것.

<aside> 💡

이제 디비버에서 만든 테이블을 자바로 옮길 것이다.

</aside>

회원가입/로그인 구현

UserDTO 클래스(Model-UserDTO 패키지)

테이블에 있는 컬럼을 보고 자바에서 클래스의 필드로 만든다

<aside> 💡

테이블에서 컬럼명은 _를 사용하는 스네이크 표기법으로 작성했으나

자바에서는 대소문자를 사용하는 카멜표기법으로 변경하여 작성한다.

</aside>

필드는 private 접근제한자를 붙인다

  • 이클립스에서 ALT+SHIFT+A로 그리드모드

getter, setter

  • ALT+SHIFT+S로 만들수 있다.

Object 클래스의 메소드 toString()을 오버라이딩 한다

  • 이클립스 자바 프로젝트에서 오라클 DBMS드라이버 추가
    • 생성한 자바 프로젝트 마우스 우클릭 > Java Build Path > Libraries > Classpath > AddExternal Jars > “C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib” > ojdbc6.jar선택 > Apply >
    • 4번째 Order and Export > Select All > Apply and Close

package com.koreait.userDTO;

public class UserDTO {
//	CREATE TABLE TBL_USER(
//			USER_NUMBER NUMBER,
//			USER_ID VARCHAR2(30),
//			USER_PW VARCHAR2(30),
//			USER_NAME VARCHAR2(30),
//			USER_AGE NUMBER,
//			USER_GENDER CHAR(1) DEFAULT 'M',
//			CONSTRAINT PK_USER PRIMARY KEY(USER_NUMBER)
//		);
	

	private int userNumber;
	private String userId;
	private String userPw;
	private String userName;
	private int userAge;
	private String userGender;
	//게터 세터 만들기
	public int getUserNumber() {
		return userNumber;
	}
	public void setUserNumber(int userNumber) {
		this.userNumber = userNumber;
	}
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getUserPw() {
		return userPw;
	}
	public void setUserPw(String userPw) {
		this.userPw = userPw;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public int getUserAge() {
		return userAge;
	}
	public void setUserAge(int userAge) {
		this.userAge = userAge;
	}
	public String getUserGender() {
		return userGender;
	}
	public void setUserGender(String userGender) {
		this.userGender = userGender;
	}
	@Override
	public String toString() {
		return "UserDTO [userNumber=" + userNumber + ", userId=" + userId + ", userPw=" + userPw + ", userName="
				+ userName + ", userAge=" + userAge + ", userGender=" + userGender + "]";
	}
	
	
}

DBConnector클래스

오라클과 연결해주는 클래스

package com.koreait.userDAO;

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

public class DBConnector {
	public static Connection getConnection() {
		//getConnection() static메서드로 만듦 > static메서드는 클래스명, 메소드명 호출해서 사용가능
		Connection connection  = null;
		//연결에 필요한 정보 입력
		String userName = "web2";
		String password = "1234";
		String url= "jdbc:oracle:thin:@localhost:1521:xe";
		//URL 주소: JDBC로 연결할떄의 URL주소 > 정해진 URL을 사용하는 것
		//1521번은 오라클의 포트번호이며, mysql은 3306이다, 그러나 JDBC연결은 다 다르므로 구글링
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			//해당 부분이 문제가 없을 경우 메모리에 올라감
			//커넥션 객체가 드라이버로 오게 된다.
			//여기서 연결 실패시 ClassNotFoundException
			connection = DriverManager.getConnection(url, userName, password);
			//여기서 연결 실패시 SQLException
			System.out.println("연결 성공");
		} catch (ClassNotFoundException e) {
			System.out.println("드라이버 로딩 실패");
			e.printStackTrace();
		} catch (SQLException e) {
			System.out.println("연결 정보 오류");
			e.printStackTrace();
		}
		return connection;
	}
}

UserDAO 클래스(Controller-UserDAO 패키지)

쿼리문이 작성되는 클래스

  • 테이블 정보 조회
  • 회원가입
  • 특정 ID가 있는지 조회(아이디 중복검사)

package com.koreait.userDAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.koreait.userDTO.UserDTO;

public class UserDAO {
	//연결, 쿼리문 실행, 결과를 받아올 수 있는 객체 선언
	public Connection connection;	//DB연결 객체
	public PreparedStatement preparedStatement;		//SQL구문을 미리 컴파일하여 실행하는 객체
	public ResultSet resultSet;		//SELECT문 실행 후 결과 테이블을 담는 객체
	
	//전체 회원 조회 메소드
	public List<UserDTO> selectAll(){		
		//여러 회원 정보를 담을 리스트 객체
		List<UserDTO>userList = new ArrayList<>();	
		//문자열 타입 쿼리문
		//실행할 SQL쿼리문
		String query = "SELECT * FROM TBL_USER ORDER BY USER_NUMBER";
		try {
			//(1) DB 연결 객체 가져오기
			connection = DBConnector.getConnection();
			//(2) SQL구문을 준비(쿼리문 미리 컴파일)
			preparedStatement = connection.prepareStatement(query);
			//(3) SQL 실행 후 결과(ResultSet) 반환
			resultSet = preparedStatement.executeQuery();
			// executeQuery(): Select실행 시 사용, 결과는 ResultSet으로 반환
			// executeUpdate(): insert, update, delete 실행시 사용, 결과는 영향받은 행의 수로 반환(int)
			
			//(4) 결과 집합(ResultSet)에서 행(Row)단위로 데이터 꺼내오기
			while(resultSet.next()) {
				UserDTO user = new UserDTO();
				user.setUserNumber(resultSet.getInt("USER_NUMBER"));
				//user.setUserNumber(resultSet.get자료형("컬럼명"));
				user.setUserId(resultSet.getString("USER_ID"));
				user.setUserPw(resultSet.getString("USER_PW"));
				user.setUserName(resultSet.getString("USER_NAME"));
				user.setUserAge(resultSet.getInt("USER_AGE"));
				user.setUserGender(resultSet.getString("USER_GENDER"));
				//리스트에 UserDTO 객체 추가
				userList.add(user);
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println("전체 회원 조회 실패(selectAll()메소드 오류 발생)");
			e.printStackTrace();
		} finally {	//사용한 자원 해제하기
			try {
				if(resultSet != null) {
					resultSet.close();
				} if(preparedStatement != null) {
					preparedStatement.close();
				} if(connection != null) {
					connection.close();
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				//자원 해제 중 오류 발생시 처리
				System.out.println("연결 해제시 오류 발생");
				e.printStackTrace();
			}
		}
		return userList;
	}
}

Statement: SQL객체를 그대로 DB에 전달

  • 매번 SQL문이 계속 전달
  • SQL에 값을 이어 붙여서 만듦.
Statement statement = connection.createStatement();
  • 매번 할때마다 SQL을 이어붙이는 식으로 사용하므로
  • 느리기도 느리고, SQL injection공격에도 취약하다.
  • 따라서 preparedStatement를 사용

PreparedStatement: 한번에 SQL문을 전달해 한번에 컴파일

  • 성능도 좋고, 안전하다.
  • ?로 된 부분을 나중에 바인딩해줄 수 있다.
//회원가입 메소드
	public void insertUser(UserDTO userDTO) {
		//원래는 그냥 VALUES했지만 자바에선 모든 컬럼을 다써주는게 좋음(성능저하문제)
		// USER_NUMBER 컬럼의 값: SEQ_USER_NO.NEXTVAL 시퀀스에서 자동 증가값 사용
		//USER_ID, USER_PW, USER_NAME, USER_AGE, USER_GENDER는 ?로 처리후 나중에 바인딩
		String query = "INSERT INTO TBL_USER(USER_NUMBER, USER_ID, USER_PW, USER_NAME, USER_AGE, USER_GENDER) "
				+ "VALUES(SEQ_USER_NO.NEXTVAL, ?, ?, ?, ?, ?)";	//쿼리문이 미완성 되었으므로 ?로 넣어줌
		try {
			//Statement의 경우에는 먼저 넣어주어야 한다. 
			//db연결 객체 생성
			// DBConnector 클래스의 getConnection() 메소드로 오라클 DB와 연결
			connection = DBConnector.getConnection();
			//SQL실행 준비
			//preparedStatement는 ?로 된 부분을 나중에 값으로 바인딩할 수 있다.
			preparedStatement = connection.prepareStatement(query);
			//1번에 값 넣어줌.(?로 된 부분 바인딩
			
			preparedStatement.setString(1, userDTO.getUserId());	
			//2번에 값 넣어줌.
			preparedStatement.setString(2, userDTO.getUserPw());
			preparedStatement.setString(3, userDTO.getUserName());
			preparedStatement.setInt(4, userDTO.getUserAge());
			preparedStatement.setString(5, userDTO.getUserGender());
			//위로인해 쿼리문이 완성되었다.
			preparedStatement.executeUpdate();	//쿼리문을 실행시켜준다(update)
		} catch (SQLException e) {
			//예외처리 SQL실행과정에서 오류가 발생하면 catch문으로 들어옴
			System.out.println("insertUser()회원가입 메소드 SQL 오류!!");
			e.printStackTrace();
		} finally {		//닫아주기
			try {
				if(preparedStatement!= null) {
					preparedStatement.close();
				}
				if(connection != null) {
					connection.close();
				}
			} catch (SQLException e) {
				System.out.println("insertUser()메소드 연결 종료 오류!");
				e.printStackTrace();
			}
		}
		
	}//insertUser 회원가입 중괄호 끝
	//아이디 중복 확인 메소드
			public boolean checkId(String userId) {
				//실행할 sql쿼리 작성
				//USER_ID가 특정 값과 일치하는 행의 user_number 조회
				//해당 아이디가 존재하는지 확인하는 용도
				try {
					String query = "SELECT USER_NUMBER FROM TBL_USER WHERE USER_ID = ?";
					
					//DB연결 객체생성
					connection = DBConnector.getConnection();
					//SQL 실행 준비
					preparedStatement = connection.prepareStatement(query);
					
					//? 바인딩
					preparedStatement.setString(1, userId);
					//결과 처리
					// resultSet.next()는 행이 존재하면 true반환
					
					resultSet = preparedStatement.executeQuery();
					//동일한 USER_ID가 이미 존재하면 TRUE > 중복아이디
					if(resultSet.next()) {
						return true;
					}
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					System.out.println("checkId() ID 중복확인 메소드 sql오류!");
					e.printStackTrace();
				} finally {
					try {
						if(resultSet != null) {
							resultSet.close();
						}
						if(preparedStatement != null) {
							preparedStatement.close();
						}
						if(connection != null) {
							connection.close();
						}
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						System.out.println("checkId() 해제 오류!");
						e.printStackTrace();
					}
				}
				return false;		

test(메인)클래스

UserDAO 클래스의 메소드 호출하는 클래스

package com.koreait.test;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import com.koreait.userDAO.DBConnector;
import com.koreait.userDAO.UserDAO;
import com.koreait.userDTO.UserDTO;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Connection connection = DBConnector.getConnection();
		//.close 메소드 사용시 예외처리 필수
		try {
			connection.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println("닫기 실패");
			e.printStackTrace();
		}
		//전체회원 조회 메소드 호출
		//1) UserDAO 객체 생성(UserDAO 안에 있는 메소드 사용)
		UserDAO userDAO = new UserDAO();
		System.out.println("user 출력 결과");
		List<UserDTO> userList = userDAO.selectAll();
		System.out.println(userList);
		for(UserDTO user: userList) {
			System.out.println(user);
		}
		
		//회원가입 위한 DTO객체 생성 및 값 설정
		UserDTO newUser = new UserDTO();
		newUser.setUserId("test");
		newUser.setUserPw("test1");
		newUser.setUserName("신짱구");
		newUser.setUserAge(5);
		newUser.setUserGender("M");
		
		userDAO.insertUser(newUser);
		//회원가입 성공
		System.out.println("회원가입 성공!");
		
		System.out.println("user 출력 결과");
		userList = userDAO.selectAll();
		System.out.println(userList);
		for(UserDTO user: userList) {
			System.out.println(user);
		}
		
		boolean idCheck = userDAO.checkId("test");
		if(idCheck) {
			System.out.println("id가 존재합니다. 다른 아이디 입력해주세요!");
		}
		else {
			System.out.println("해당 아이디를 사용할 수 있습니다!");
		}
	}

}

로그인 메소드

메소드명: login

리턴타입: String(이름)

매개변수: String userId, String userPw

쿼리문:SELECT user_name FROM tbl_user WHERE user_id = ? AND user_pw = ?

반환: 로그인 성공시 이름 반환

	   //4. 로그인 메소드
	   public String login(String userId, String userPw) {
	      //1) 실행할 SQL 쿼리 작성
	      //입력받은 ID와 PW가 일치하는 사용자의 USER_NAME을 조회
	      String query = "SELECT USER_NAME FROM TBL_USER WHERE USER_ID = ? AND USER_PW = ?";
	      
	      //2) 로그인 성공 시 반환할 사용자 이름을 담을 변수 선언
	      String name = null;
	      
	      try {
	         //3) DB 연결 객체 생성
	         connection = DBConnector.getConnection();
	         
	         //4) SQL 실행 준비(쿼리문 미리 컴파일)
	         preparedStatement = connection.prepareStatement(query);
	         
	         //5) ? 바인딩(순서대로 userId, userPw)
	         preparedStatement.setString(1, userId);
	         preparedStatement.setString(2, userPw);
	         
	         //6) SQL문 실행(SELECT문이므로 executeQuery() 사용 - 담아줄 변수 ResultSet 타입의 객체로 만든다)
	         resultSet = preparedStatement.executeQuery();
	         
	         //7) 결과 처리
	         //resultSet.next()가 true라면 로그인 정보가 일치하는 사용자 존재 => 로그인 성공
	         //false라면 로그인 정보가 일치하는 사용자 미존재 => 로그인 실패
	         if(resultSet.next()) {
	            //USER_NAME 컬럼값을 name변수에 저장
	            name = resultSet.getString("USER_NAME");
	            //System.out.println("로그인 성공!! " + name + "님 환영합니다!");
	         }else {
	            System.out.println("로그인 실패! 아이디 또는 비밀번호가 일치하지 않습니다");
	         }
	      } catch (SQLException e) {
	         // TODO Auto-generated catch block
	         //8) SQL 실행 중 오류 발생시 예외처리
	         System.out.println("login() 로그인 메소드 SQL 오류!!");
	         e.printStackTrace();
	      } finally {
	         //9) 사용한 자원 해제(연결 종료)
	         //resultSet -> preparedStatement -> connection 순서로 진행
	         try {
	            if(resultSet != null) {
	               resultSet.close();
	            }
	            if(preparedStatement != null) {
	               preparedStatement.close();
	            }
	            if(connection != null) {
	               connection.close();
	            }
	         } catch (SQLException e) {
	            // TODO Auto-generated catch block
	            System.out.println("login() 연결 종료 오류!!");
	            e.printStackTrace();
	         }
	         
	      }
	      
	      //10) 최종적으로 name 반환
	      //로그인 성공시 사용자 이름, 실패시 null 반환
	      return name;
	      
	   }
//메인메소드
//로그인 메소드 호출
		//while문의 조건식에서 비교대상이 될 변수
		int count = 0;
		//상수(항상 같은 값) 대문자로 쓰고 _로 연결해서 선언
		final int MAX_ATTEMPT = 3;	//상수선언 final을 이용
		//상태를 확인해줄 플래그 변수
		boolean isLogin = false;
		//while문을 통한 반복문
		while (count < MAX_ATTEMPT) {
			Scanner sc = new Scanner(System.in);
			//입력 받기 위한 출력문
			System.out.println("아이디 입력:");
			String userId = sc.nextLine();
			System.out.println("비밀번호 입력:");
			String userPw = sc.nextLine();
			//로그인 시도
			String name=  userDAO.login(userId, userPw);
			if(name != null) {
				System.out.println("로그인 성공!! " + name + "님 환영합니다!");	
				isLogin = true;	//로그인 성공 후 더이상 로그인 시도 못하도록
				break;		//로그인 성공 시 반복문 종료
			}
			else {
				count++;
				System.out.println("로그인 실패"
							+ "(" + "/" + MAX_ATTEMPT + ")");
			}
		}
		if(!isLogin) {
			System.out.println("로그인 3회 실패! 프로그램 종료");
		}

비밀번호 변경 메소드

메소드명: changePw

리턴타입: boolean

매개변수 : String userId(현재 아이디), String currentPw(현재비밀번호), String newPw(새로운 비밀번호)

쿼리문 : UPDATE tbl_user SET USER_PW = ? WHERE USER_ID = ? AND USER_PW = ?;

public boolean changePw(String userId, String currentPw, String newPw) {
		   //업데이트 쿼리 작성
		   String query = "UPDATE tbl_user SET USER_PW = ? WHERE USER_ID = ? AND USER_PW = ?";
		   
		   try {
			   connection = DBConnector.getConnection();
			   preparedStatement = connection.prepareStatement(query);
			   preparedStatement.setString(1, newPw);
			   preparedStatement.setString(2, userId);
			   preparedStatement.setString(3, currentPw);
			   //정수형 변수 결고 저장
			   int result = preparedStatement.executeUpdate();
			   //반환값
			   return result > 0;
		   } catch (SQLException e) {
			   System.out.println("changePw() 메소드 오류");
			   e.printStackTrace();
		   }finally {
			   try {
		            if(preparedStatement != null) {
		               preparedStatement.close();
		            }
		            
		            if(connection != null) {
		               connection.close();
		            }
		         } catch (SQLException e) {
		            // TODO Auto-generated catch block
		            System.out.println("changePw() 연결 종료 오류!!");
		            e.printStackTrace();
		         }
		   }
		   
		   return false;
	   }
		Scanner sc = new Scanner(System.in);
		
		System.out.println("아이디 입력 : ");
		String userId = sc.nextLine();
		
		System.out.println("기존 비밀번호 입력:");
		String userPw=  sc.nextLine();
		
		System.out.println("새로운 비밀번호 입력:");
		String newPw = sc.nextLine();
		
		boolean chPw = userDAO.changePw(userId, userPw, newPw);
		if(chPw) {
			System.out.println("비밀번호가 성공적으로 변경되었습니다");
		}
		else {
			System.out.println("비밀번호 변경이 실패했습니다.");
		}

회원탈퇴 메소드

메소드명: deleteUser

리턴타입: boolean

매개변수: int userNumber

쿼리문: DELETE FROM TBL_USER WHERE user_number = ?;

//6. 회원탈퇴 메소드
	   public boolean deleteUser(int userNumber) {
	      //1) 실행할 SQL문 쿼리 작성
	      String query = "DELETE FROM TBL_USER WHERE USER_NUMBER = ?";
	      
	      try {
	         //2) DB 연결객체 생성
	         connection = DBConnector.getConnection();
	         
	         //3) SQL 실행 준비
	         preparedStatement = connection.prepareStatement(query);
	         
	         //4) ? 바인딩
	         //USER_NUMBER의 값을 채워야하므로 매개변수로 받은 userNumber를 첫번째 ?에 세팅
	         preparedStatement.setInt(1, userNumber);
	         
	         //5) SQL 실행
	         int result = preparedStatement.executeUpdate();
	         System.out.println("=====삭제된 행 수 : " + result + "======");
	         //6) result > 0 true라면 성공적으로 데이터가 삭제(회원탈퇴 완료)
	         return result > 0;
	      } catch (SQLException e) {
	         // TODO Auto-generated catch block
	         System.out.println("deleteUser() SQL 오류!!");
	         e.printStackTrace();
	      } finally {
	         try {
	            if(preparedStatement != null) {
	               preparedStatement.close();
	            }
	            if(connection != null) {
	               connection.close();
	            }
	         } catch (SQLException e) {
	            // TODO Auto-generated catch block
	            e.printStackTrace();
	         }
	      }   
	      return false;
	   } // deleteUser 메소드 중괄호 끝 영역
	   	   
			

'RDBMS' 카테고리의 다른 글

MySQL JDBC로 구현  (0) 2025.11.11
MySQL 설치 및 기본 문법 등  (1) 2025.11.07
3. DDL, DML, DCL, TCL  (0) 2025.10.28
2. 제약조건(오라클)  (0) 2025.10.25
1. SQL 문 (오라클)  (0) 2025.10.23