빅데이터 서비스 교육/Java

Java JDBC

Manly 2022. 5. 6. 10:48
반응형

 

View

package View;

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

import Model.Student;
import Model.StudentDAO;
import controller.Controller;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		// 데이터베이스와 접근하는 도구 꺼내오기
		Controller c = new Controller();

		System.out.println("==========SMHRD학생관리프로그램=========");
		while (true) {
			System.out.println("1.학생추가 2.전체명단조회 3.특정학생조회 4.학생정보수정 5.학생삭제 6.프로그램종료");

			System.out.print("메뉴선택 >> ");
			int menu = sc.nextInt();

			if (menu == 1) {
				System.out.println("등록할 학생의 정보를 입력하시오");
				System.out.print("학번 : ");
				int stdnum = sc.nextInt();
				System.out.print("이름 : ");
				String name = sc.next();
				System.out.print("나이 : ");
				int age = sc.nextInt();
				System.out.print("전화번호 : ");
				String tel = sc.next();
				System.out.print("이메일 : ");
				String email = sc.next();

				Student s = new Student(stdnum, name, age, tel, email);
				c.insert(s);

			} else if (menu == 2) {
			c.selectAll();

			} else if (menu == 3) {
				// 1. 학생번호 입력받기
				System.out.print("조회하고 싶은 학생번호 입력 : ");
				int stdnum = sc.nextInt();
				
				c.selectOne(stdnum);

			} else if (menu == 4) {
				// 학생번호를 입력받아서 해당하는 학생의 정보수정
				System.out.print("수정하고 싶은 학생번호 입력 : ");
				int stdnum = sc.nextInt();

				c.update(stdnum);

			} else if (menu == 5) {
				System.out.println("5번선택");
				// 이름을 입력받아서 해당하는 데이터를 삭제!
				System.out.println("삭제할 학생의 이름을 입력하시오");
				System.out.print("이름 : ");
				String name = sc.next();
				System.out.print("이메일 : ");
				String email = sc.next();
				// Student s = new Student(name,0,null,email);
				// 위처럼 쓸 수 있지만 메소드 오버로딩을 통해 name,email
				// 두개를 매개변수로 받는 생성자를 새로 만든다.
				Student s = new Student(name, email);
				c.delete(s);
				
			} else if (menu == 6) {
				System.out.println("프로그램 종료!");
				break;
			}
		}

	}

}

DAO - sql문

package Model;

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

import oracle.net.aso.s;

public class StudentDAO {

	// 1.필드
	private ResultSet rs = null;
	private PreparedStatement psmt = null;
	private Connection conn = null;

	// 2.메소드
	// 데이터베이스와 연결하는 메소드
	private void getConn() {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			String url = "jdbc:oracle:thin:@localhost:1521:xe";
			//url을 잘못쓰면 Listener 오류가 뜬다.
			String user = "hr";
			String password = "hr";
			conn = DriverManager.getConnection(url, user, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	// 자원반납하는 메소드
	private void getClose() {
		try {
			if (rs != null)
				rs.close();
			if (psmt != null)
				psmt.close();
			if (conn != null)
				conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public int insert(Student s) {
		int row = 0;
		try {
			getConn();
			String sql = "insert into student values(stdseq.nextval,?,?,?,?)";
			psmt = conn.prepareStatement(sql);
			psmt.setString(1, s.getName());
			psmt.setInt(2, s.getAge());
			psmt.setString(3, s.getTel());
			psmt.setString(4, s.getEmail());
			row = psmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			getClose();
		}
		return row;
	}

	public int delete(Student s) {
		int row = 0;
		try {
			getConn();
			String sql = "delete from student where name = ? and email = ?";
			psmt = conn.prepareStatement(sql);
			psmt.setString(1, s.getName());
			psmt.setString(2, s.getEmail());
			row = psmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			getClose();
		}
		return row;
	}

	public ArrayList<Student> selectAll() {
		ArrayList<Student> al = new ArrayList<Student>();
		try {
			getConn();
			String sql = "select * from student";
			psmt = conn.prepareStatement(sql);
			rs = psmt.executeQuery();
			while (rs.next()) {
				;
				int stdnum = rs.getInt(1);
				String name = rs.getString(2);
				int age = rs.getInt("age");
				String tel = rs.getString("tel");
				String email = rs.getString("email");
				Student s = new Student(stdnum, name, age, tel, email);
				al.add(s);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			getClose();
			}
		return al;
	}

	public Student selectOne(int stdnum) {
		Student s = null;
		try {
			getConn();
			String sql = "select * from student where stdnum = ?";
			psmt = conn.prepareStatement(sql);
			psmt.setInt(1, stdnum);
			rs = psmt.executeQuery();
			if (rs.next()) {
				int get_stdnum = rs.getInt("stdnum");
				String name = rs.getString("name");
				int age = rs.getInt("age");
				String tel = rs.getString("tel");
				String email = rs.getString("email");
				s = new Student(get_stdnum, name, age, tel, email);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			getClose();
		}
		return s;
	}

	public int updateOne(Student updateS) {
		int row = 0;
		try {
			getConn();
			String sql = "update student set name=?,age=?,tel=?,email=? where stdnum =? ";
			psmt = conn.prepareStatement(sql);
			psmt.setString(1, updateS.getName());
			psmt.setInt(2, updateS.getAge());
			psmt.setString(3, updateS.getTel());
			psmt.setString(4, updateS.getEmail());
			psmt.setInt(5, updateS.getStdnum());
			
			row = psmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			getClose();
		}
		return row;
	
		//stdnum을 기준으로 이름, 나이 , 전화번호, email을 수정하는 sql문 작성
	}
}

복습용 줄이지 않은 DAO

package Model;

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

import oracle.net.aso.s;

public class preStudentDAO {
	// 첫번째로 DAO 버전 --> 공부하라고 남겨 놓는다.

	// 1. 학생 추가 (Student 테이블에 값 삽입) 메소드
	// 메소드 내에서 외부 객체가 가지고 있는 값을 써야하는 경우
	// 무조건 매개변수로 그 외부 객체 혹은 써야하는 값을 매개변수로 넣어줘야 한다.
	public int insert(Student s) {
		// JDBC
		// 예외처리(Exception)
		// 오류의 종류
		// 1)컴파일오류: 오타, 변수이름 동일.. -> 실행 자체가 안된다.
		// 2)런타임오류: 실행 중에 오류가 발생
		// -> 예외처리 ex) (try~catch)문
		// try: 실행 할 로직
		// catch: 예외가 발생 했을 때 실행할 구문
		// (개발중에는 오류의 종류를 출력 / 서비스중에는 오류문구)
		// finally: try에서 예외가 발생하던지 하지 않던지
		// 무조건 실행하는 부분(DB 연결 종료도 해주어야 한다)
		Connection conn = null; // 레퍼런스형의 기본값 = null
		PreparedStatement psmt = null;
		int row = 0;
		try {
			// 1. JDBC 라이브러리 동적 로딩 필요
			// 동적 로딩: 실행하는 순간에 자료형을 결정해주는 것

			// ClassNotFoundException이라는 예외상황이 발생하면
			// 1)작성한 문자열에 오타가 있을 경우
			// 2)라이브러리를 추가하지 않았을 경우
			Class.forName("oracle.jdbc.driver.OracleDriver");
			// java buildpath에서 classpath에 ojdb6.jar파일 선택
			// project에 해당 파일을 넣어야 라이브러리 동적 로딩이 된다.

			// getConnection에는 문자열로 url,계정명,패스워드 을 써주면 된다.
			String url = "jdbc:oracle:thin:@localhost:1521:xe";
			// jdbc:oracle:thin --> oracle에 thin드라이버를 사용한다는 의미
			// @localhost --> ip주소
			// 1521 --> portnumber
			// xe --> DB의 별칭
			String user = "hr";
			String password = "hr";

			// 2. DB연결 = connection 객체 생성
			conn = DriverManager.getConnection(url, user, password);
			// 얘도 SQLException을 캐치문에

			// 3. 실행할 sql 정의 (문자열로)
			// student --> table --> column??
			// stdnum, name, age, tel, email
			String sql = "insert into student values(stdseq.nextval,?,?,?,?)";
			// 고정값을 넣을 수 없기때문에 물음표인자를 넣는다
			// 4. sql 문장을 전송할 수 있는 형태로 담아주기
			psmt = conn.prepareStatement(sql);
			// 5. ? 인자를 채우기
			// ?인자는 1부터 시작
			psmt.setString(1, s.getName());
			psmt.setInt(2, s.getAge());
			psmt.setString(3, s.getTel());
			psmt.setString(4, s.getEmail());
			// 6. 데이터베이스에 쿼리문 전송하기
			row = psmt.executeUpdate();
			// executeUpdate(): 행의 개수를 반환한다, DML 사용
			// DML : insert, update, delete / 테이블에 영향을 주는 쿼리문
			// int row --> 테이블에서 영향을 받은 행의 개수

			// 예외가 발생 했을 때 실행 할 구간
		} catch (ClassNotFoundException e) {
			// ClassNotFoundException 처리 catch문
			e.printStackTrace(); // 예외상황을 순서대로 콘솔에 출력
		} catch (SQLException e) {
			// SQLException 처리 catch문
			e.printStackTrace();
			// 예외상황이 발생했을때 해당하는 예외상활을
			// 추적하면서 쌓아서 출력해준다. -> 배포할땐 삭제해라

			// 예외가 발생해도 한번은 실행해주는 구간
		} finally { // 생략가능
			// 7. 자원반납
			// conn, psmt를 반납하는데 예외 실행시 한번은 실행해주는 finally에서 자원반납 한다.
			// ** 자원반납할때는 연결한 순서의 역순으로 반납해야한다
			try {
				if (psmt != null)
					psmt.close();
				if (conn != null)
					conn.close(); // if문안에 로직이 하나면 중괄호 생략가능

			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("데이터 자원반납 시 오류");
			}

		}
		return row;
		// row가 try안에서만 작동하는 지역변수니까 row를 try문 밖에서 선언해주고
		// try문에서 row값을 넣고, 리턴하면 구문이 끝나버리니까 finally끝나고 리턴
	}

	public int delete(Student s) {
		int row = 0; // 결과값
		Connection conn = null;
		PreparedStatement psmt = null;

		// 1. 데이터베이스 연결
		// 1-1) 오라클 드라이버 동적 로딩(바인딩)
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			// forName 메소는 throws ClassNotfoundException 설계때부터 가지고 있다
			// -> 예외상황을 무조건 한번은 잡아주도록(try catch문으로 잡아주도록) 강제성이있다!

			// 1-2) 데이터베이스 연결
			String url = "jdbc:oracle:thin:@localhost:1521:xe";
			String user = "hr";
			String password = "hr";
			conn = DriverManager.getConnection(url, user, password);

			// 2. 쿼리문 작성 후 전송
			// 쿼리문 --> 이름과 이메일이 모두 일치하는 학생정보를 삭제
			String sql = "delete from student where name = ? and email = ?";

			// 2-1) sql문장을 전송할 수 있게 형식에 맞게 담아주기
			psmt = conn.prepareStatement(sql);
			// 2-2) ?인자 채우기
			psmt.setString(1, s.getName());
			psmt.setString(2, s.getEmail());
			// 2-3) 전송
			row = psmt.executeUpdate();
			// 3. 결과를 이용한 작업처리(return 키워드로 대신함)

			// catch(Exception e){
			// Exception e = new ClassNotFoundException();
			// 업캐스팅 사용해서 한번에 처리 가능, 모든 예외상황은 부모클래스로 Exceotion }

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 4. 자원반납
			try {
				if (psmt != null)
					psmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		return row;
	}

	// 내가만든거
	public int delete2(Student s) {
		int row = 0; // 결과값
		Connection conn = null;
		PreparedStatement psmt = null;

		try {
			// 1. 데이터베이스 연결
			Class.forName("oracle.jdbc.driver.OracleDriver");
			String url = "jdbc:oracle:thin:@localhost:1521:xe";
			String user = "hr";
			String password = "hr";
			conn = DriverManager.getConnection(url, user, password);
			// 2. 쿼리문 작성 후 전송
			// 쿼리문 --> 이름과 이메일이 모두 일치하는 학생정보를 삭제
			String sql = "delete from student where name = ? and email = ?";

			psmt = conn.prepareStatement(sql);
			psmt.setString(1, s.getName());
			psmt.setString(2, s.getEmail());

			row = psmt.executeUpdate();

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (psmt != null)
					psmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		// 3. 결과를 이용한 작업처리(return 키워드로 대신함)

		// 4. 자원반납

		return row;
	}

	public ArrayList<Student> selectAll() {
		ArrayList<Student> al = new ArrayList<Student>();
		ResultSet rs = null;
		PreparedStatement psmt = null;
		Connection conn = null;

		try {
			// 1. 오라클 드라이버 동적 로딩
			Class.forName("oracle.jdbc.driver.OracleDriver");
			String url = "jdbc:oracle:thin:@localhost:1521:xe";
			String user = "hr";
			String password = "hr";

			// 2. DB 연결 객체(Connection) 생성
			conn = DriverManager.getConnection(url, user, password);

			// 3. SQL문 정의
			String sql = "select * from student";

			// 4. SQL문 실행 객체(PreparedStatement) 생성
			psmt = conn.prepareStatement(sql);

			// 5. SQL문 실행하고 결과처리
			// executeUpdate: insert, delete, update문 실행시 사용
			// : 테이블 상에 변화가 일어난경우, int(반환타입): 테이블상에 변화가 일어난 행의 수

			// executeQuery: select문 실행 시 사용
			// : 테이블 상에 변화가 일어나지 않은 경우, ResultSet(반환타입)
			// ResultSet: 한행씩 결과를 볼수 있고,커서가 가르키고 있지 않은 행은 볼수없다
			// ResultSet안의 next()라는 메소드로 커서를 한칸 움직인다.
			// next()는 커서가 움직였을때 데이터가 있는지 없는지 판단

			rs = psmt.executeQuery();

			while (rs.next()) {
				; // 커서를 한칸 움직이고 데이터가 있으면 조건문 실행
					// getInt() : ResultSet 객체의 특정 컬럼이름(or순서) 을 지정하여 값을 가지고 오는 메서드(정수형)
				int stdnum = rs.getInt(1);
				// getString() : ResultSet 객체의 특정 컬럼이름(or순서) 을 지정하여 값을 가지고 오는 메서드(문자열)
				String name = rs.getString(2);
				int age = rs.getInt("age");
				String tel = rs.getString("tel");
				String email = rs.getString("email");

				Student s = new Student(name, age, tel, email);
				al.add(s);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 6. 연결 종료 자원 반환
			try {
				rs.close();
				psmt.close();
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
		return al;
	}

	// 3. selectOne 메서드 작성하기
	// 1. 학생을 식별할 수 있는 값 필요! (매개변수)
	// 2. 반환타입 주의 - 학생 한명에 대한 정보만 반환
	// 3. sql작성
	public Student selectOne(int stdnum) {
		
		Student s = null;
		ResultSet rs = null;
		PreparedStatement psmt = null;
		Connection conn = null;

		try {
			//1. jdbc 드라이버 동적 로딩
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url = "jdbc:oracle:thin:@localhost:1521:xe";
			String user = "hr";
			String password = "hr";
			//2. Connection 객체 생성
			conn = DriverManager.getConnection(url, user, password);

			//3. SQL문 정의
			String sql = "select * from student where stdnum = ?";
			
			//4. sql실행(PreparedStatement) 객체 생성
			psmt = conn.prepareStatement(sql);
			//5. ?(바인드 변수) 자리 채우기
			psmt.setInt(1, stdnum);
			//6. sql문 실행 및 결과처리		
			rs = psmt.executeQuery();

			
			if (rs.next()) {
				//입력한 학생번호가 실제 존재할 경우
				int get_stdnum = rs.getInt("stdnum");
				String name = rs.getString("name");
				int age = rs.getInt("age");
				String tel = rs.getString("tel");
				String email = rs.getString("email");

				s = new Student(get_stdnum, name, age, tel, email);

			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if(rs!=null)
				rs.close();
				if(psmt!=null)
				psmt.close();
				if(conn!=null)
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return s;
	}
}

 

Class

package Model;

public class Student {
	// 필드, 메소드(생성자), getter, setter
	private int stdnum;
	private String name;
	private int age;
	private String tel;
	private String email;

	@Override
	public String toString() {
		return "학생번호 : " +stdnum+"\n이름 : "+name+"\n나이 : "+age+"\n전화번호 : "+tel+
				"\n이메일 : "+email;
				}

	public Student(int stdnum, String name, int age, String tel, String email) {
		this.stdnum = stdnum;
		this.name = name;
		this.age = age;
		this.tel = tel;
		this.email = email;
	}
	//모르고 매개변수에 int stdnum 넣어서 아래 Student 그대로 오버로딩해서 매개변수 숫자만 다르게 해서 썼다.

	public Student(String name, int age, String tel, String email) {
		this.name = name;
		this.age = age;
		this.tel = tel;
		this.email = email;
	}

	// 생성자를 중복으로 정의하는 기법 --> 오버로딩!
	public Student(String name, String email) {
		this.name = name;
		this.email = email;
	}

	public int getStdnum() {
		return stdnum;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	public String getTel() {
		return tel;
	}

	public String getEmail() {
		return email;
	}

}

Controller

package controller;

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

import Model.Student; //ctrl+shift+o   import 단축키
import Model.StudentDAO;

public class Controller {
//view --> controller -> Model (DAO) --> Controller -> View로 설계할거
	// 1. 필드
	private StudentDAO dao = new StudentDAO();
	private Scanner sc = new Scanner(System.in);

	// 학생추가 메소드

	public void insert(Student s) {
		int row = dao.insert(s);
		if (row > 0) {
			System.out.println("학생추가 성공");
		} else {
			System.out.println("학생추가 실패");
		}
	}

	// 학생정보 전체조회
	public void selectAll() {
		ArrayList<Student> al = dao.selectAll();
		for (Student s : al) {
			//주소값을 가진 레퍼런스 변수를 넣었을때 내가 원하는 형식으로 출력할 수 있게 해주는 매소드
			//tostring() -> Onject가 가지고 있는 메소드  --> 오버라이딩해서 사용가능
		
			System.out.println(s);
			System.out.println("==============");
			}
	}

	public void selectOne(int stdnum) {
		// 2. DAO 클래스 - selectOne() 호출
		Student s = dao.selectOne(stdnum);
		if (s != null) {
			System.out.println(s);
			System.out.println("=========================");
		} else {
			System.out.println("없는 학생번호입니다.");
		}
		
	}

	public void update(int stdnum) {
		// 학생정보가 있다면 수정 할 수 있게 만들어주기
		// 1. 학생정보가 있는가?
		// -> 테이블에 데이터가 존재하는가?
		Student s = dao.selectOne(stdnum);
		if (s != null) {
			System.out.println(s.getName() + "님의 정보를 수정합니다.");
			System.out.print("학번 : ");
			int stdnum1 = sc.nextInt();
			System.out.println("이름 : ");
			String name = sc.next();
			System.out.println("나이 : ");
			int age = sc.nextInt();
			System.out.println("전화번호 : ");
			String tel = sc.next();
			System.out.println("이메일 : ");
			String email = sc.next();
			Student updateS = new Student(stdnum, name, age, tel, email);
			int row = dao.updateOne(updateS);
			if (row > 0) {
				System.out.println("학생정보 수정 성공");
			} else {
				System.out.println("학생정보 수정 실패");
			}

		}
		
	}

	public void delete(Student s) {
		int row = dao.delete(s);
		if (row > 0) {
			System.out.println("학생정보삭제 성공");
		} else {
			System.out.println("학생정보삭제 실패");
		}

		
	}

}

sql.sql 간단

connection profile

type -> oracle11           / New orcle    Database: xe

create table student(
stdnum number(3), name varchar2(30),
age number(3), tel varchar2(50),
email varchar2(100)
)
insert into student values(stdseq.nextval,'강예진',25,'010-0000-0000','kyg4914@gmail.com');

CREATE SEQUENCE stdseq
INCREMENT BY 1 
START WITH 1 
MINVALUE 1 
MAXVALUE 1000 
NOCYCLE 
NOCACHE; 

select * from student

drop table student



drop table student

반응형

'빅데이터 서비스 교육 > Java' 카테고리의 다른 글

Java Interface  (0) 2022.05.06
Java 추상클래스  (0) 2022.05.06
Java 상속  (0) 2022.05.06
Java Arraylist  (0) 2022.05.06
Java OOP  (0) 2022.05.06