[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 클래스
- 사용자의 입력값을 저장하는 클래스
javapackage 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문을 쓰는 클래스를 별도로 생성해야 함
javapackage 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 : 데이터를 전달해주고 사라진다.
javapackage 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문
javapackage 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)

(2) - 수정(update)

(3) - 삭제(delete)

(4) - 전체 출력(selectAll)

(5) - 이름 검색(searchName)

(6) - 학번 검색(searchHak)

CallableStatement 메서드(프로시저 사용)를 사용해서 SQL문을 실행하는 성적 입력 프로그램 만들기
- Score : 사용자의 입력값을 저장하는 클래스
- ScoreDAO : Data Access Object / SQL문을 작성하여 데이터를 처리하는 클래스(PreparedStatement 사용)
- ScoreDTO : Data Transfer Object / DB에 데이터를 전달하는 역할을 하는 클래스
- ScoreMain : 메인 클래스
이 방법은 ScoreDAO 클래스를 제외한 나머지 3개 클래스는 상단 코드와 동일하다.
먼저 cmd창에서 프로시저를 생성해준다.


다음으로 계속 cmd 창에서 하단 프로시저들을 생성해줘야 한다.
성적 입력 프로시저 - insertScore 생성하기
sqlcreate 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;

성적 수정 프로시저 - updateScore 생성하기
sqlcreate 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;

데이터 삭제 프로시저 - deleteScore 생성하기
sqlcreate or replace procedure deleteScore (pHak in score.hak%type) is begin delete score where hak=pHak; commit; end;

데이터 전체 조회 프로시저 - selectAll 생성하기
sqlcreate 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;

이름 검색 프로시저 - selectNameScore 생성하기
sqlcreate 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;

학번 검색 프로시저 - selectHakScore 생성하기
sqlcreate 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;

프로시저를 생성한 후에 ScoreDAO 클래스를 만들어준다.
ScoreDAO 클래스
sqlpackage 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를 써서 만든 성적 프로그램과 같은 결과가 나온다!
끝!
블로그의 정보
무작정 개발
무작정 개발