무작정 개발.Vlog

[JDBC] PreparedStatement문, CallableStatement, 성적 입력 프로그램 만들기

by 무작정 개발
반응형
2022.02.07(31일 차)

 

JDBC 2일 차

 

select 된 값을 pResult(커서)에 넣어주고 out(출력)한다. 전체 데이터를 출력하니 매개변수 필요 x

오늘의 수업 내용

 

오늘은  Statement 메서드를 사용해서 SQL문 실행하는 성적 입력 프로그램을 만든다. 

저번 시간에 Statement에 대해 배웠다.

 

Statement 인터페이스 종류 3가지

  • Statement
  • PreparedStatement
  • CallableStatement

 

위 3가지 인터페이스가 있다. 우리는 PreparedStatement와 CallableStatement를 각각 사용해서 성적 입력 프로그램을 만들 것이다.


PreparedStatement 메서드를 사용해서 SQL문을 실행하는 성적 입력 프로그램 만들기

 

  • Score : 사용자의 입력값을 저장하는 클래스
  • ScoreDAO2 : Data Access Object / SQL문을 작성하여 데이터를 처리하는 클래스(PreparedStatement 사용)
  • ScoreDTO : Data Transfer Object / DB에 데이터를 전달하는 역할을 하는 클래스
  • ScoreMain : 메인 클래스

패키지 안에 위의 4가지 클래스를 넣어서 만들 것이다.

 

 

(1) - Score 클래스

  • 사용자의 입력값을 저장하는 클래스
package com.score6;

import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

// 여기에는 사용자한테 데이터를 받는 곳
//영어점수 내놔, 데이터 수정하고 싶어(삭제,변경 등)
public class Score {
	
	Scanner sc = new Scanner(System.in);
	
	ScoreDAO dao = new ScoreDAO(); //객체 생성
	
	
	//입력
	public void insert() {
		
		
		
		try {
			
			ScoreDTO dto = new ScoreDTO(); //사용자 입력 데이터를 담을 dto 객체 생성
			
			System.out.print("학번?"); //111
			dto.setHak(sc.next());
			
			System.out.print("이름?");//suzi
			dto.setName(sc.next()); // dto의 setName
			
			System.out.print("국어?");//50
			dto.setKor(sc.nextInt());
			
			System.out.print("영어?");//70
			dto.setEng(sc.nextInt());
			
			System.out.print("수학?");//60
			dto.setMat(sc.nextInt());
			
			
			int result = dao.insertData(dto);
			
			if(result !=0)
				System.out.println("추가 성공!!");
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
	}
	
	
	//수정
	public void update() { //반환값이 없으니 void
		
		ScoreDTO dto = new ScoreDTO(); //객체 생성
		
		try {
			
			System.out.print("수정할 학번?");
			dto.setHak(sc.next());
			
			System.out.print("국어?");
			dto.setKor(sc.nextInt());
			
			System.out.print("영어?");
			dto.setEng(sc.nextInt());
			
			System.out.print("수학?");
			dto.setMat(sc.nextInt());
			
			//실행하면 result 반환
			int result = dao.updateDate(dto); //dto를 넘겨주면서 이 데이터를 수정해달라 요청
			
			//정상적으로 잘 실행됬다면
			if(result != 0) {
				System.out.println("수정성공!!!");
			}
			
			
		} catch (Exception e) {
			System.out.println(e.toString()); //에러 처리
		}
		
		//void라서 반환값이 없다!
	}
	
	//삭제 메서드
	public void delete() {
		
		String hak; //학번만 받으면 되니 hak 선언
		
		try {
			
			System.out.print("삭제할 학번?");
			hak = sc.next();
			
			int result = dao.deleteData(hak);
			
			if(result != 0) {
				System.out.println("삭제 성공!!");
			}
			
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		//void를 써서 반환값 필요없움
		
	}
	
	//전체출력
	public void selectAll() {
		
		List<ScoreDTO> lists = dao.getList();
		
		Iterator<ScoreDTO> it = lists.iterator();
		
		while(it.hasNext()) {
			ScoreDTO dto = it.next();
			System.out.println(dto.toString());
		}
	}
	
	//이름검색
	public void searchName() {
		
		String name;
		
		try {
			
			System.out.println("검색할 이름?");
			name = sc.next();
			
			List<ScoreDTO> lists = dao.getList(name);
			
			Iterator<ScoreDTO> it = lists.iterator();
			
			while(it.hasNext()) {
				ScoreDTO dto = it.next();
				System.out.println(dto.toString());
			}
			
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
	}
	
	//학번검색
		public void searchHak() {
			
			String hak;
			
			try {
				
				System.out.print("검색할 학번?");
				hak = sc.next();
				//오버라이딩 했어도 매개변수 타입이 같기 때문에 이름을 바꿔줘야한다. getList -> getHakList
				//학번은 primarykey라서 dto를 1개 가져오거나 안가지고 와서 lists,list 대신 dto를 쓴다.
				//이렇게되면 iterator도 필요없어진다.그리고 while문도 필요없어진다.

				ScoreDTO dto = dao.getHakList(hak);
				
				if(dto != null) {  //검증작업 dto가 null이 아니면
					
					//ScoreDTO의 toString호출
					System.out.println(dto.toString());
				}
				
				
			} catch (Exception e) {
				System.out.println(e.toString()); 
			}
		}

}

 

(2) - ScoreDAO2

  • Data Access Object / SQL문을 작성해서 데이터를 처리하는 클래스(PreparedStatement 사용)
  • PreparedStatement : SQL문을 입력받으면 먼저 유효한 쿼리인지 확인 후 statement에 할당
  • SQL문을 쓰는 클래스를 별도로 생성해야 함
package com.score6;
//preparedStatement
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.db.DBConn;

//여기는 DB에 연동해서 query(쿼리)를 실행하는 곳

public class ScoreDAO2 { // Data Access Object
	
	//입력 - DTO의 데이터를 받을 매개변수 준비
	public int insertData(ScoreDTO dto) {
		
		//DTO를 전달받아 입력 진행/dto는 전달만 해주고 사라진다.
		int result = 0; //result는 DB가 잘 실행되면 1값 안되면 0값을 반환한다.
		
		//DB연결
		Connection conn = DBConn.getConnection();
		
		//DB한테 가서 쿼리를 실행해주는애가 statement인데 우린 prepared를 씀
		PreparedStatement pstmt = null;
		String sql;
		
		//try문에서 문제 발생시 sql문 자체의 문제이거나, 실행시 문제
		try {
			/*
			//이게 Statement 방식이다.복잡하다. 그래서 우린 PreparedStatement방식을 씀 -눈도장만 찍기
			//값은 사용자한테 받아야하니 여기서 잠깐 멈추고Score에가서 만들어준다.
			sql = "insert into score (hak,name,kor,eng,mat) ";
			sql+= "values ('" + dto.getHak() + "','"; // 학번은 DTO에 들어가있다.
			sql+= dto.getName() + ",'";
			sql+= dto.getKor() + ",";
			sql+= dto.getMat() + ",";
			sql+= dto.getEng() + ")";
			*/
			
			//PreparedStatement방식
			sql = "insert into score (hak,name,kor,eng,mat) ";
			sql+= "values (?,?,?,?,?)"; //입력할 데이터가 5개면 ?를 5개 찍어주면 된다.
			
			//statement connection이 만듬
			//pre는 미리 준비해서 미리 sql를 가져가서 검사를 받는다. 그냥 statement는 중간에서 가져가서 검사함
			pstmt = conn.prepareStatement(sql);//데이터가 이상이 없으면 pstmt에 넣는다.
			
			//데이터 넣어주기
			pstmt.setString(1, dto.getHak());//이름이니String / 이름은 첫번째 ? 라서 1 / 어디에있나? getHak에 있다.
			pstmt.setString(2, dto.getName());
			pstmt.setInt(3, dto.getKor());
			pstmt.setInt(4, dto.getEng());
			pstmt.setInt(5, dto.getMat());
			
			//완벽한 sql 실행
			//PreparedStatement에서 이미 검사를 진행해서 매개변수 없이 실행
			result = pstmt.executeUpdate(); //잘 실행되면 1, 아니면 0을 반환
			
			pstmt.close(); //다썻으면 DB닫아주기
			
		} catch (Exception e) {
			
			System.out.println(e.toString());
			
		}
		
		return result; //result 반환
	}
	
	
	//데이터 수정(update)
	public int updateDate(ScoreDTO dto) {
		
		int result = 0;
		
		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;//인터페이스도 클래스다. 클래스의 초기값은 null이다.
		
		String sql;
		
		try {
			
			sql = "update score set kor=?,eng=?,mat=? where hak=?"; //데이터를 ?로 표시하는게 preparedstatement이다.
			
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setInt(1, dto.getKor());
			pstmt.setInt(2, dto.getEng());
			pstmt.setInt(3, dto.getMat());
			pstmt.setString(4, dto.getHak());
			
			//실행
			result = pstmt.executeUpdate(); // 0아니면 1 값이 나옴
			
			pstmt.close(); // 닫아주고
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return result;
		
		
	}
	
	//삭제(delete)
	
	//삭제는 dto 전부를 받을 필요가 없다.학번String하나만 입력받아도 문제없음
	public int deleteData(String hak) { //삭제할땐 학번만 받으면되니 ScoreDTO대신 String hak
		
		int result = 0;
		
		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;
		
		String sql;
		
		try {
			
			sql = "delete score where hak=?";
			
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, hak); //매개변수가 학번 1개이므로 바로 할당해주면 된다.
			
			result = pstmt.executeUpdate();
			
			pstmt.close(); //닫기
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return result;
		
	}
	
	//전체 출력(selectAll) : dto에 담길 list가 필요하다.
	// - DB에서 select해서 DAO에 넣고 score에 넘겨주고 score에서 데이터를 출력한다.
	public List<ScoreDTO> getList() {
		
		List<ScoreDTO> lists = new ArrayList<ScoreDTO>();
		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;//select문의 경우 테이블을 반환하기 때문에 ResultSet을 사용
		
		String sql;
		
		try {
			
			sql = "select hak,name,kor,eng,mat, ";
			sql+= "(kor+eng+mat) tot,(kor+eng+mat)/3 ave, ";
			sql+= "rank() over (order by (kor+eng+mat) desc) rank ";
			sql+= "from score";
			
			pstmt = conn.prepareStatement(sql);
			
			// 여긴 ?가 없어서 실행만 하면 된당
			
			//실행된 결과를 rs가 받는다
			rs = pstmt.executeQuery();
			
			//테이블에 레코드가 있을 때까지 반복
			while(rs.next()) {
				
				//레코드에 있는 내용을 dto에 입력
				ScoreDTO dto = new ScoreDTO(); //데이터의 갯수만큼 만들어줘야하기때문에 while문 안에 생성
				
				dto.setHak(rs.getString("hak")); //rs에 있는 String형태의 hak을 가져온다.
				dto.setName(rs.getString(2)); // 2 는 name이다. 번호를 써줬음 여기서는 하지만 회사에는 번호는 거의 안쓴다.
				dto.setKor(rs.getInt("kor"));
				dto.setEng(rs.getInt("eng"));
				dto.setMat(rs.getInt("mat"));
				dto.setTot(rs.getInt("tot"));
				dto.setAve(rs.getInt("ave"));
				dto.setRank(rs.getInt("rank"));
				
				lists.add(dto); //위의 데이터(dto)들을 lists에 넣어준다.
				
			}
			
			rs.close(); //반복이 끝나면 닫아주고
			pstmt.close();
			
			
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return lists; //반환값은 DTO가 들어있는 lists를 반환
		
	}
	
	//이름 검색(searchName)
	public List<ScoreDTO> getList(String name) { //오버로딩
		
		List<ScoreDTO> lists = new ArrayList<ScoreDTO>();
		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		String sql;
		
		try {
			
			sql = "select hak,name,kor,eng,mat,";
			sql+= "(kor+eng+mat) tot,(kor+eng+mat)/3 ave ";
			sql+= "from score where name like ?";
			
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, name + "%");
			
			// 여긴 ?가 없어서 실행만 하면 된당
			
			//실행된 결과를 rs가 받는다
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				
				ScoreDTO dto = new ScoreDTO(); //데이터의 갯수만큼 만들어줘야하기때문에 while문 안에 생성
				
				dto.setHak(rs.getString("hak")); //rs에 있는 String형태의 hak을 가져온다.
				dto.setName(rs.getString(2)); // 2 는 name이다. 번호를 써줬음 여기서는 하지만 회사에는 번호는 거의 안쓴다.
				dto.setKor(rs.getInt("kor"));
				dto.setEng(rs.getInt("eng"));
				dto.setMat(rs.getInt("mat"));
				dto.setTot(rs.getInt("tot"));
				dto.setAve(rs.getInt("ave"));
				
				lists.add(dto); //위의 데이터들을 lists에 넣어준다.
				
			}
			
			rs.close(); //반복이 끝나면 닫아주고
			pstmt.close();
			
			
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return lists; //반환값은 DTO가 들어있는 lists를 반환

	}
	
	//학번 검색(searchHak)
	//--학번 검색은 있으면 나오고 없으면 안나온다.
		public ScoreDTO getHakList(String hak) {
			
			//학번이 기본키라서 데이터(레코드)가 1개라서 list를 쓸 필요가 없다.
			// 여기서는 객체 생성이 필요없는게 데이터가 있으면 객체를 생성해서 담으면 되고,
			//없으면 객체를 생성할 필요가 없어서 null로 선언만 해놓은다.
			//검색한 데이터가 결과가 없을수도 있어 객체를 null로 생성해도된다.
			ScoreDTO dto = null;
			Connection conn = DBConn.getConnection();
			PreparedStatement pstmt = null;
			ResultSet rs = null;
			
			String sql;
			
			try {
				
				sql = "select hak,name,kor,eng,mat,";
				sql+= "(kor+eng+mat) tot,(kor+eng+mat)/3 ave ";
				sql+= "from score where hak=?";
				
				pstmt = conn.prepareStatement(sql);
				
				pstmt.setString(1, hak);
				
				// 여긴 ?가 없어서 실행만 하면 된당
				
				//실행된 결과를 rs가 받는다
				rs = pstmt.executeQuery();
				
				//데이터가 있거나 없거나 둘중 하나
				if(rs.next()) { //rs에 데이터가 있으면 출력해라
					
					dto = new ScoreDTO(); //데이터의 갯수만큼 만들어줘야하기때문에 while문 안에 생성
					
					//레코드에 있는 내용을 dto에 입력
					dto.setHak(rs.getString("hak")); //rs에 있는 String형태의 hak을 가져온다.
					dto.setName(rs.getString(2)); // 2 는 name이다. 번호를 써줬음 여기서는 하지만 회사에는 번호는 거의 안쓴다.
					dto.setKor(rs.getInt("kor"));
					dto.setEng(rs.getInt("eng"));
					dto.setMat(rs.getInt("mat"));
					dto.setTot(rs.getInt("tot"));
					dto.setAve(rs.getInt("ave"));
					
				}
				
				rs.close(); //반복이 끝나면 닫아주고
				pstmt.close();
				
				
				
			} catch (Exception e) {
				System.out.println(e.toString());
			}
			
			return dto; //반환값은 dto

		}
}

 

(3) - ScoreDTO

  • Data Transfer Object / DB에 데이터를 전달하는 역할을 하는 클래스
  • 기존에는 VO를 생성해서 ScoreVO를 list에 담았지만, 지금은 DB를 배웠으니 DB를 연동해서 이름을 DTO로 해줌
  • DTO : 데이터를 전달해주고 사라진다.
package com.score6;
//오늘 하는건 끝나는 날까지함 매우 중요함!!!
//DB에서는 VO대신 DTO로 만듬
public class ScoreDTO { // data transfer object - 데이터를 전달하는 객체
	
	//DB에 존재하는 컬럼
	//DB에 데이터를 입력할땐 이 5개의 변수만씀
	private String hak;
	private String name;
	private int kor;
	private int eng;
	private int mat;
	
	//DB에 존재하지 않는 컬럼
	//DB에서 데이터를 꺼내올때는 아래 3개포함 총 8개의 변수를 씀
	private int tot;
	private int ave;
	private int rank;
	
	
	//마우스 우클릭-> source ->getters & setters 해서 모두 체크!
	public String getHak() {
		return hak;
	}
	
	public void setHak(String hak) {
		this.hak = hak;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getKor() {
		return kor;
	}
	
	public void setKor(int kor) {
		this.kor = kor;
	}
	
	public int getEng() {
		return eng;
	}
	
	public void setEng(int eng) {
		this.eng = eng;
	}
	
	public int getMat() {
		return mat;
	}
	
	public void setMat(int mat) {
		this.mat = mat;
	}
	
	public int getTot() {
		return tot;
	}
	
	public void setTot(int tot) {
		this.tot = tot;
	}
	
	public int getAve() {
		return ave;
	}
	
	public void setAve(int ave) {
		this.ave = ave;
	}
	
	public int getRank() {
		return rank;
	}
	
	public void setRank(int rank) {
		this.rank = rank;
	}
	
	//toString 오버라이드
	@Override
		public String toString() {
		
			String str;
			
			str = String.format("%6s %8s %4d %4d %4d %4d %4d %4d", 
					hak,name,kor,eng,mat,tot,ave,rank);
			
			return str;
			
		}
}

 

(4) - ScoreMain

  • Main문
package com.score6;
//여기서 나오는 추가수정삭제등 총6개 메서드는 꼭 외우기 엄청 중요함!!!!!
import java.util.Scanner;

//메뉴가 있는곳
public class ScoreMain {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		Score ob = new Score(); //객체생성 - (포함관계)
		
		int ch;
		
		while(true) {
			
			do {
				System.out.print("1.추가 2.수정 3.삭제 4.전체출력 5.이름검색 6.학번검색 7.종료");
				ch = sc.nextInt();//값은 ch로 받을거다.
				
			} while(ch<1||ch>7);
			
			switch(ch) { //메뉴를 누르면 Score 의 insert가 실행되야하니 위에  Score 객체생성해주기
			
			case 1:
				ob.insert();
				break;
			case 2:
				ob.update();
				break;
			case 3:
				ob.delete();
				break;
			case 4:
				ob.selectAll();
				break;
			case 5:
				ob.searchName();
				break;
			case 6:
				ob.searchHak();
				break;
				
			default:
				System.exit(0);
			
			}
		} //여기까지 while(true)
		

	}
}

 

실행결과

 

(1) - 추가(insert)

(1) - 추가(insert)
(1) - 추가(insert)

 

(2) - 수정(update)

(2) - 수정(update)
(2) - 수정(update)

 

(3) - 삭제(delete)

(3) - 삭제(delete)
(3) - 삭제(delete)

 

(4) - 전체 출력(selectAll)

(4) - 전체 출력(selectAll)
(4) - 전체 출력(selectAll)

 

(5) - 이름 검색(searchName)

(5) - 이름 검색(searchName)
(5) - 이름 검색(searchName)

 

(6) - 학번 검색(searchHak)

(6) - 학번 검색(searchHak)
(6) - 학번 검색(searchHak)


CallableStatement 메서드(프로시저 사용)를 사용해서 SQL문을 실행하는 성적 입력 프로그램 만들기

  • Score : 사용자의 입력값을 저장하는 클래스
  • ScoreDAO : Data Access Object / SQL문을 작성하여 데이터를 처리하는 클래스(PreparedStatement 사용)
  • ScoreDTO : Data Transfer Object / DB에 데이터를 전달하는 역할을 하는 클래스
  • ScoreMain : 메인 클래스

 

이 방법은 ScoreDAO 클래스를 제외한 나머지 3개 클래스는 상단 코드와 동일하다.

 

먼저  cmd창에서 프로시저를 생성해준다.

cmd창에서 프로시저를 생성
suzi계정한테 프로시저 권한을 주고 프로시저 만들기

 

프로시저 생성 확인
프로시저 생성 확인

다음으로 계속 cmd 창에서  하단 프로시저들을 생성해줘야 한다.

 

 

성적 입력 프로시저 - insertScore 생성하기

create or replace procedure insertScore
(pHak in score.hak%type,
pName in score.name%type,
pKor in score.kor%type,
pEng in score.eng%type,
pMat in score.mat%type)
is
begin
insert into score (hak,name,kor,eng,mat)
values (pHak,pName,pKor,pEng,pMat);
commit;
end;

성적 입력 프로시저 - insertScore 생성하기
성적 입력 프로시저 - insertScore 생성하기

 

 

성적 수정 프로시저 - updateScore 생성하기

create or replace procedure updateScore
(pHak in score.hak%type,
pKor in score.kor%type,
pEng in score.eng%type,
pMat in score.mat%type)
is
begin
update score set kor=pKor, eng=pEng, mat=pMat where hak=pHak;
commit;
end;

성적 수정 프로시저 - updateScore 생성하기
성적 수정 프로시저 - updateScore 생성하기

 

 

데이터 삭제 프로시저 - deleteScore 생성하기

create or replace procedure deleteScore
(pHak in score.hak%type)
is
begin
delete score where hak=pHak;
commit;
end;

데이터 삭제 프로시저 - deleteScore 생성하기
데이터 삭제 프로시저 - deleteScore 생성하기

 

 

데이터 전체 조회 프로시저 - selectAll 생성하기

create or replace procedure selectAllScore
(pResult out sys_refcursor)
is
begin
open pResult for
select hak,name,kor,eng,mat,
(kor+eng+mat) tot, (kor+eng+mat)/3 ave,
rank() over (order by (kor+eng+mat) desc) rank
from score order by hak;
end;

데이터 전체 조회 프로시저 - selectAll 생성하기
데이터 전체 조회 프로시저 - selectAll 생성하기

 

이름 검색 프로시저 - selectNameScore 생성하기

create or replace procedure selectNameScore
(pResult out sys_refcursor, pName in varchar2)
is
begin
open pResult for
select hak,name,kor,eng,mat,
(kor+eng+mat) tot, (kor+eng+mat)/3 ave
from score where name like pName || '%';
end;

이름 검색 프로시저 - selectNameScore 생성하기
이름 검색 프로시저 - selectNameScore 생성하기

 

 

학번 검색 프로시저 - selectHakScore 생성하기

create or replace procedure selectHakScore
(pResult out sys_refcursor, pHak in varchar2)
is
begin
open pResult for
select hak,name,kor,eng,mat,
(kor+eng+mat) tot, (kor+eng+mat)/3 ave
from score where hak=pHak;
end;

학번 검색 프로시저 - selectHakScore 생성하기
학번 검색 프로시저 - selectHakScore 생성하기

프로시저를 생성한 후에  ScoreDAO 클래스를 만들어준다.

 

ScoreDAO 클래스

package com.score6;
import java.sql.CallableStatement;
//앤 프로시저 -프로시저는 회사에서 프로시저로 하면 하고 우리는 statement로 할거다
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.db.DBConn;

import oracle.jdbc.OracleTypes; //오라클 타입 import

//여기는 DB에 연동해서 query(쿼리)를 실행하는 곳

public class ScoreDAO { // Data Access Object
	
	//입력 - DTO의 데이터를 받을 매개변수 준비
	public int insertData(ScoreDTO dto) {
		
		int result = 0; //result는 DB가 잘 실행되면 1값 안되면 0값을 반환한다.
		
		//DB연결
		Connection conn = DBConn.getConnection();
		
		//프로시저를 호출해서 실행시키는 statement
		CallableStatement cstmt = null;
		String sql;
		
		try {
			
			
			//프로시저 호출 방법 : 중괄호 { }
			sql = "{call insertScore(?,?,?,?,?)}"; 
			
			
			cstmt = conn.prepareCall(sql);
			
			//데이터 넣어주기
			cstmt.setString(1, dto.getHak());//이름이니String / 이름은 첫번째 ? 라서 1 / 어디에있나? getHak에 있다.
			cstmt.setString(2, dto.getName());
			cstmt.setInt(3, dto.getKor());
			cstmt.setInt(4, dto.getEng());
			cstmt.setInt(5, dto.getMat());
			
			//완벽한 sql 실행
			result = cstmt.executeUpdate(); //잘 실행되면 1, 아니면 0을 반환
			
			cstmt.close(); //다썻으면 DB닫아주기
			
		} catch (Exception e) {
			
			System.out.println(e.toString());
			
		}
		
		return result; //result 반환
	}
	
	
	//데이터 수정(update)
	public int updateDate(ScoreDTO dto) {
		
		int result = 0;
		
		Connection conn = DBConn.getConnection();
		CallableStatement cstmt = null;//인터페이스도 클래스다. 클래스의 초기값은 null이다.
		
		String sql;
		
		try {
			
			sql = "{call updateScore(?,?,?,?)}";
			
			cstmt = conn.prepareCall(sql);
			
			cstmt.setString(1, dto.getHak());
			cstmt.setInt(2, dto.getKor());
			cstmt.setInt(3, dto.getEng());
			cstmt.setInt(4, dto.getMat());
			
			
			//실행
			result = cstmt.executeUpdate(); // 0아니면 1 값이 나옴
			
			cstmt.close(); // 닫아주고
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return result;
		
		
	}
	
	//삭제(delete)
	public int deleteData(String hak) { //삭제할땐 학번만 받으면되니 ScoreDTO대신 String hak
		
		int result = 0;
		
		Connection conn = DBConn.getConnection();
		CallableStatement cstmt = null;
		
		String sql;
		
		try {
			
			sql = "{call deleteScore(?)}";
			
			cstmt = conn.prepareCall(sql);
			
			cstmt.setString(1, hak); // hak으로 받으니 hak써줌
			
			result = cstmt.executeUpdate();
			
			cstmt.close(); //닫기
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return result;
		
	}
	
	//전체 출력
	//--전체출력은 바꿀것이 많다
	public List<ScoreDTO> getList() {
		
		List<ScoreDTO> lists = new ArrayList<ScoreDTO>();
		Connection conn = DBConn.getConnection();
		CallableStatement cstmt = null;
		ResultSet rs = null;
		
		String sql;
		
		try {
			//select한 데이터가 (?) 안으로 들어간다.
			sql = "{call selectAllScore(?)}";
			
			cstmt = conn.prepareCall(sql);
			
			//out 파라미터의 자료형을 설정 (?)는 오라클에서 처리해줘야한다. ?는 데이터타입이 커서 타입
			cstmt.registerOutParameter(1, OracleTypes.CURSOR); //오라클 타입이 안나옴.why? 라이센스 문제때문에
			//그래서 외부라이브러리 등록을 해줘야 한다.
			
			//프로시저 실행
			cstmt.executeUpdate();
			
			//out 파라미터의 값을 돌려 받기 - 오라클에서 받으니까 object로받기
			rs = (ResultSet)cstmt.getObject(1); //object로 받았으니 down-casting
			
			while(rs.next()) {
				
				ScoreDTO dto = new ScoreDTO(); //데이터의 갯수만큼 만들어줘야하기때문에 while문 안에 생성
				
				dto.setHak(rs.getString("hak")); //rs에 있는 String형태의 hak을 가져온다.
				dto.setName(rs.getString(2)); // 2 는 name이다. 번호를 써줬음 여기서는 하지만 회사에는 번호는 거의 안쓴다.
				dto.setKor(rs.getInt("kor"));
				dto.setEng(rs.getInt("eng"));
				dto.setMat(rs.getInt("mat"));
				dto.setTot(rs.getInt("tot"));
				dto.setAve(rs.getInt("ave"));
				dto.setRank(rs.getInt("rank"));
				
				lists.add(dto); //위의 데이터들을 lists에 넣어준다.
				
			}
			
			rs.close(); //반복이 끝나면 닫아주고
			cstmt.close();
			
			
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return lists; //반환값은 DTO가 들어있는 lists를 반환
		
	}
	
	//이름 검색 - 여기 프로시저 수정하기 이름@@@@@@@@@@@@@@@@@@2
	public List<ScoreDTO> getList(String name) { //오버로딩
		
		List<ScoreDTO> lists = new ArrayList<ScoreDTO>();
		Connection conn = DBConn.getConnection();
		CallableStatement cstmt = null;
		ResultSet rs = null;
		
		String sql;
		
		try {
			
			sql = "{call selectNameScore(?,?)}"; //여긴 값이 2개 받는값, 집어넣는 값
			
			cstmt = conn.prepareCall(sql);
			
			
			
			//out 파라미터 자료형 설정
			cstmt.registerOutParameter(1, OracleTypes.CURSOR);
			
			//in 파라미터
			cstmt.setString(2, name);
			
			//프로시저 실행
			cstmt.executeUpdate();
			
			//out 파라미터 값 받기
			rs = (ResultSet)cstmt.getObject(1);
			
			while(rs.next()) {
				
				ScoreDTO dto = new ScoreDTO(); //데이터의 갯수만큼 만들어줘야하기때문에 while문 안에 생성
				
				dto.setHak(rs.getString("hak")); //rs에 있는 String형태의 hak을 가져온다.
				dto.setName(rs.getString(2)); // 2 는 name이다. 번호를 써줬음 여기서는 하지만 회사에는 번호는 거의 안쓴다.
				dto.setKor(rs.getInt("kor"));
				dto.setEng(rs.getInt("eng"));
				dto.setMat(rs.getInt("mat"));
				dto.setTot(rs.getInt("tot"));
				dto.setAve(rs.getInt("ave"));
				
				lists.add(dto); //위의 데이터들을 lists에 넣어준다.
				
			}
			
			rs.close(); //반복이 끝나면 닫아주고
			cstmt.close();
			
			
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return lists; //반환값은 DTO가 들어있는 lists를 반환

	}
	
	//학번 검색
	//--학번 검색은 있으면 나오고 없으면 안나온다.
		public ScoreDTO getHakList(String hak) {
			
			//여기서도 list가 필요없어서 ScoreDTO한다. 그리고 ScoreDTO는 객체생성할 필요가 없어서 null로
			ScoreDTO dto = null;
			Connection conn = DBConn.getConnection();
			CallableStatement cstmt = null;
			ResultSet rs = null;
			
			String sql;
			
			try {
				
				sql = "{call selectHakScore(?,?)}";
				
				cstmt = conn.prepareCall(sql);
				
				//out 파라미터 자료형 설정
				cstmt.registerOutParameter(1, OracleTypes.CURSOR);
				
				//in 파라미터
				cstmt.setString(2, hak);
				
				//프로시저 실행
				cstmt.executeUpdate();
				
				//out 파라미터 값 받기
				rs = (ResultSet)cstmt.getObject(1);
				
				if(rs.next()) { //rs에 데이터가 있으면 출력해라
					
					dto = new ScoreDTO(); //데이터의 갯수만큼 만들어줘야하기때문에 while문 안에 생성
					
					dto.setHak(rs.getString("hak")); //rs에 있는 String형태의 hak을 가져온다.
					dto.setName(rs.getString(2)); // 2 는 name이다. 번호를 써줬음 여기서는 하지만 회사에는 번호는 거의 안쓴다.
					dto.setKor(rs.getInt("kor"));
					dto.setEng(rs.getInt("eng"));
					dto.setMat(rs.getInt("mat"));
					dto.setTot(rs.getInt("tot"));
					dto.setAve(rs.getInt("ave"));
					
				}
				
				rs.close(); //반복이 끝나면 닫아주고
				cstmt.close();
				
				
			} catch (Exception e) {
				System.out.println(e.toString());
			}
			
			return dto; //반환값은 dto

		}
}

여기서 전체 출력 부분을 보자

노란색 부분을 쓰기 위해서는 외부 라이브러리를 등록해줘야 한다.

외부 라이브러리를 등록
외부 라이브러리를 등록

이렇게 ojdbc6.jar를 등록해주면 오라클 타입을 선언할 수 있다.

 

 

 

이렇게 프로시저를 생성해주고 ScoreMain 클래스를 실행하면 위의 PreparedStatement를 써서 만든 성적 프로그램과 같은 결과가 나온다!

 

 


끝!

반응형

블로그의 정보

무작정 개발

무작정 개발

활동하기