Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.

학생관리 프로그램

자바 스탠다드 및 JDBC연동 교육후 한 팀 프로젝트

  3조 : 최규식, 김양군, 김흥섭, 변정훈, 오도현, 권성기
 
  ------------------------------------------------------
                        기능
  ------------------------------------------------------
       1. 학생 개인정보 간리
       2. 출석체크(지각 및 조퇴처리)
       3. 학생 성적 관리
       4. 벌금 부과
 
  ------------------------------------------------------
                          DB
  ------------------------------------------------------
       student - 메인 테이블, 학생 개인 정보 관리
                    필드 : ID  NOT NULL  VARCHAR2(15) PRIMARY KEY //회원 아이디  
                             PASSWORD  NOT NULL  VARCHAR2(15)  //비밀번호
                             NAME  NOT NULL  VARCHAR2(15)  //이름
                             NO  NOT NULL  NUMBER(3)  //회원 등급 1:학생 2:관리자
                             ADDR     VARCHAR2(40)  //주소
                             BIRTHDAY     VARCHAR2(20)  //생년월일 (년/월/일)
       attend - 출석을 위한 테이블
                   필드 :  SEQ  NOT NULL  NUMBER(5) PRIMARY KEY // attend_seq 시퀀스 사용  
                             ID  NOT NULL  VARCHAR2(15) FOREIGN KEY REFERENCE STUDENT //아이디
                             ATTEND     VARCHAR2(10)   // 출석체크, 출석하면 1, 아니면 0 or null
                             LATE     VARCHAR2(10)  //지각체크, 지각하면 1, 아니면 0 or null
                             EARLY     VARCHAR2(10)  //조퇴체크, 조퇴하면 1, 아니면 0 or null
                             FINISH     VARCHAR2(10)  //퇴근체크, 퇴근하면 1, 아니면 0 or null
                             ADATE     VARCHAR2(20)  //시간 기록 (월/일 시각:분)
        grade - 성적관리를 위한 테이블
                   필드 : SEQ  NOT NULL  NUMBER(10) PRIMARY KEY //grade_seq 시퀀스 사용
                            ID  NOT NULL  VARCHAR2(15) FOREIGN KEY REFERENCE STUDENT //아이디
                            GRADE     VARCHAR2(10)  //성적
                            SUBJECT     VARCHAR2(10)  //과목명
        penalty - 벌금 관리를 위한 테이블
                     필드 : SEQ  NOT NULL  NUMBER(5)  PRIMARY KEY //penalty_seq 시퀀스 사용
                              ID  NOT NULL  VARCHAR2(15) FOREIGN KEY REFERENCE STUDENT //아이디
                              AMOUNT     NUMBER(10)  //벌금 금액
                              WHY     VARCHAR2(20)  //벌금 부과 이유
                              PDATE     VARCHAR2(20)  //시간 기록 (월/일 시각:분)
 
  -----------------------------------------------------
                          클래스
  ------------------------------------------------------
     com.project.admin ->  AdminAttendControl //출석 수정
        AdminAttendSelect //출석 열람
        AdminControlMenu //관리(수정)메뉴 선택부
        AdminGradeControl //성적 수정
        AdminGradeSelect //성적 열람
        AdminMenu //로그인한 사용자가 관리자일때 호출되는 어드민 메인
        AdminPenaltyControl //벌금 수정
        AdminPenaltySelect //벌금 열람
        AdminSelectMenu //열람메뉴 선택부
        AdminStudentControl //학생정보 수정
        AdminPenaltySelect //학생정보 보기
 
    com.project.dao -> AbstractDao //드라이버로딩과 클로즈를 위한 추상클래스. 다른 DAO가 상속받음.
        AttendDao //attend 테이블에 대한 쿼리를 위한 DAO
        GradeDao //grade 테이블에 대한 쿼리를 위한 DAO
        PenaltyDao //penalty 테이블에 대한 쿼리를 위한 DAO
        StudentDao //student 테이블에 대한 쿼리를 위한 DAO
 
    com.project.dto -> AttendDto //attend 테이블을 위한 DTO
        GradeDto //grade 테이블을 위한 DTO
        PenaltyDto //penalty 테이블을 위한 DTO
        StudentDto //student 테이블을 위한 DTO
    com.project.main -> LogInProCess //로그인 및 회원가입 처리
 
        StudentTestMain //메인!!!!
        Users //로그인한 사용자가 학생일 경우
 
    com.project.util -> SceneUtil //메인에서 사용할 화면전환 상수모음
        StudentMethod //공통적으로 사용될 메서드 모음
        StudentUtil //DB 쿼리를 위한 상수모음
 

  • 중간까지 주석열심히 달다가 다른 진도 쫓아가느라고 포기.
  • 정리된 소스가 아니라서 남이 보면 이해못할 가능성 높음.

프로젝트 후...

  • 팀프로젝트로 입사를 같이 할것이기 때문에 다른 조와 다르게 마인드맵 프로그램으로 모든 클래스와 메서드에 대한 이름과 반환값, 아규먼트를 2-3시간동안 작업해서 완료함.
  • 팀원들간 실력차이가 나는 관계로 미리 협의한대로 작성되지 않은 부분이 많아서 결국은 다시 일일이 보며 수정을 해야 했음!
  • 나름 초기에 모든 메서드를 정의한다고 생각했지만 의외로 빠진 부분도 많았고 아규먼트나 반환값에서 잘못된 부분도 상당부분이 있었음.
  • 역시 팀으로 하는 것은 쉽지 않다는 생각.
  • 마인드 맵으로 미리 모든 것을 정의한것은 잘 했다고 생각. 약간의 여유와 서로 의논의 시간이 있었다면 분업해서 해볼 수 있었을 거라고 생각됨.
  • 하지만 같은 얘기를 할때도 머릿속에 그리고 있는 생각이 서로 다른 경우가 많았고 그 결과 작성된 코드의 형태에서 많은 차이를 보이게 됨. 이런건 어떻게 해결해야 할지 잘 모르겠음.
  • 클래스를 나누어서 작성했지만 합쳐서 돌아갈수 있도록 하는 과정에서 결국은  전체소스를 보면서 버그없이 돌아갈 수 있도록 하기 위해 한사람이 수정작업을 해야해서 결과적으론 다시 한사람이 프로그램을 짜는 형태가 되어버림. 이것두 어떻게 해결해야 할지 잘 모르겠음.
2007/05/17 11:35 2007/05/17 11:35

JDBC 사용 예제

JDBC에 사용예제...

이클립스에서 작성하였기 때문에 package 사용하였슴.
각자환경에서 사용하려면 com.ksic.util에서 StudentsUtil의 DB부분을 설정에 맞게 수정해 주어야 함.

오라클 9i와 연동하여 작성한 것임.

DB테이블 명은 hkstudents이고 컬럼은 모두 varchar2타입으로 id, name, addr 3개가 있음.

테이블에 대한 DTO가 따로 하나 있고... DAO는 연결과 클로즈부분만 추상클래스로 따로 구성됨.

나름 주석 열심히 달아서 보면 이해가 될지도..



JDBC에 대한 설명

자바에서 오라클을 연결해서 사용할때 총 6단계의 과정을 거친다.

1. 드라이버 로딩
Class.forName("oracle.jdbc.driver.OracleDriver");

Class.forName으로 JDBC 드라이버를 로딩해 준다. 이 부분은 ClassNotFoundException 핸들링을 해주어야 하므로 try-catch문으로 감싸주어야 한다.

2. DB 연결
Connection conn = null;
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORA92", "scott", "tiger");


Connection을 사용하기 위해서는 java.sql.Connection 을 임포트 해주어야 한다. conn이라는 커넥션을 만든 후에 DriverManager의 getConnection을 통해서 DB를 연결해 준다. DriverManager를 사용하려면 java.sql.DriverManager를 import해주어야 한다.

첫 매계변수는 DB연결쪽이다. jdbc:oracle:thin:@부분은 동일하게 사용하고 localhost는 위치를 말한다. 다른PC이거나 할 경우는 IP를 입력해 주고 1521은 해당포트이며 ORA92는 오라클의 SID이다. 자신에 맞게 입력해준다.
두번째와 세번째는 오라클의 아이디와 패스워드이다.

이 연결부는 SQLException예외처리로 Try-Catch로 감싸 주어야 한다.

3. 쿼리 준비
PreparedStatement psmt = null;
psmt = conn.prepareStatement("DB쿼리문");
혹은
Statement stmt = null;
stmt = conn.createStatement("DB쿼리문");


를 사용한다. 각각 java.sql.PreparedStatement이나 java.sql.Statement을 임포트 해주어야 한다. Statement가 PreparedStatement보다 상위클래스이다.

실행하기 전에 DB쿼리를 준비하는 단계인데 둘의 차이는 PreparedStatement는 쿼리문에 ?를 사용해서 추가로 ?에 변수를 할당해 줄수 있다는 것이다.
psmt = conn.prepareStatement("select * from TableName where id=?");
psmt.setString(1, id);
와 같이 사용이 가능하다. setString(혹은 setInt 등등)을 이용해서 1번째 ?위치에 id를 할당할 수 있어서 유연성있게 쿼리준비를 할 수 있다.

4. 쿼리 실행
psmt.executeUpdate();
로 쿼리를 실행한다. insert, update, delete 등 값을 받아 오지 않는 쿼리문은 executeUpdate를 이용해서 실행해 준다.

5. 데이터 가져오기
select등 쿼리실행후에 값을 가져와야 하는 쿼리문의 경우는
ResultSet rs = null;
rs = psmt.executeQuery();


java.sql.ResultSet을 이용해서 쿼리실행 한 것을 ResultSet으로 받아들인다. 이때 쿼리실행은 executeQuery()를 사용한다.

그 후에

while(rs.next()) {
    int i=1;
    String id = rs.getString(i++);
    String name = rs.getString(i++);
    String addr = rs.getString(i++);
   }


rs.next()를 이용해서 한 줄씩 읽어들인다. 처음에는 시작위치에 있고 rs.next()를 실행하면 받아온 데이터의 첫줄 위치로 이동하게 된다. while문 혹은 if문을 통해서 rs.next()가 null인지를 확인하면서 반복문을 돌린다.
rs.get을 이용해서 값을 가져와 변수 혹은 dto객체등에 저장해서 사용한다. DB에 여러줄을 가져올때는 dto객체로 받아서 컬렉션 계열로 저정해야 한다.

6. 커넥션 닫기
if (rs!=null) {
   try {
      rs.close();
   } catch (SQLException e) {
   }
}
 
if(stmt!=null) {
   try {
      stmt.close();
   } catch (SQLException e) {
   }
}
 
if(conn!=null) {
   try {
      conn.close();
   } catch (SQLException e) {
   }
}

닫을때는 Open한 반대의 순서로 닫아주어야 한다. Statement가 PreparedStatement 보다 상위클래스이기 때문에 닫는 메서드를 만들때 Statement로 받을어도 PreparedStatement을 정상적으로 받을 수 있다. 닫을때는 습관적으로 null이 아닌지를 확인한 뒤에 받도록 만들면 생각지 못한 오류를 막을 수 있다.


이것이 JDBC의 기본적인 구조인데 실제적으로 사용할때는 제공되는 커넥션풀(ConnectionPool)등을 사용해서 이미 만들어진 커넥션을 사용하기 때문에 1번 과정은 pass하고 2번과정부터 커넥션풀에서 커넥션을 얻어오는 방식으로 사용하게 되는 경우가 많다.
2007/05/17 11:10 2007/05/17 11:10