JDBC 예제(CURD 게시판)

부트캠프(END)/Oracle|2022. 6. 29. 12:51

012345
*Swing 구현 코드는 생략할 것임*

일단 간단한 데이터베이스 생성

CREATE TABLE freeboard(
	no NUMBER,--sequence
	name VARCHAR2(34) CONSTRAINT fb_name_nn NOT NULL,--작성자
	subject VARCHAR2(2000) CONSTRAINT fb_subject_nn NOT NULL,
	content CLOB CONSTRAINT fb_content_nn NOT NULL,
	pwd VARCHAR2(10) CONSTRAINT fb_pwd_nn NOT NULL,
	regdate DATE DEFAULT sysdate,
	hit NUMBER DEFAULT 0,--조회수
	CONSTRAINT fb_no_pk PRIMARY KEY(no)
)

CREATE TABLE boardMember(
	id VARCHAR2(20),
	pwd VARCHAR2(10) CONSTRAINT bm_pwd_nn NOT NULL,
	name VARCHAR2(34) CONSTRAINT bm_name_nn NOT NULL,
	CONSTRAINT bm_id_pk PRIMARY KEY(id)
	
INSERT INTO boardMember VALUES('kim','1234','kimdoodoo')
INSERT INTO boardMember VALUES('lee','1234','lee')
INSERT INTO boardMember VALUES('park','1234','park')
INSERT INTO boardMember VALUES('jung','1234','jung')
INSERT INTO boardMember VALUES('kang','1234','kang')
	
COMMIT;

(좌) boardMember, (우) freeBoard

위 데이터를 저장할 클래스는 아래와 같이 정의한다.

package curd;
import java.util.Date;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
//오라클에서 데이터를 받아올 프로그램
public class BoardVO { //Value Object
	private int no;
	private String name;
	private String subject;
	private String content;
	private String pwd;
	private Date regdate;
	private int hit;
}

오라클을 자바로 가져오는 프로그램 = DAO

 

 

BoardDAO.java

1. JDBC 연결

JDBC는 자바에서 제공하는 것이 아니다. 각 데이터베이스에서 제공한다.

그렇기 때문에, JDBC 를 이용하기 위해서는 꼭 외부 라이브러리 파일을 적용해 주어야 한다.

연결 객체 Connection은 서버와 클라이언트를 연결하기 위한 Socket을 포함하고,

SQL 문장을 전송해서 결과값을 가져오는 PreparedStatement는 BufferedReader와 OutputStream을 포함한다.

package curd;
import java.util.*; //게시물 한 개를 저장하는 VO를 모아 저장할 Collection
import java.sql.*; //Connection, Statement, ResultSet
public class BoardDAO {
    //드라이버 설정->오라클 연결->SQL문장 전송->결과값 받기->오라클 닫기
    //연결 객체 설정
    private Connection conn;
    //SQL문장을 전송해서 결과값을 가져오는 객체
    private PreparedStatement ps;
    //오라클 서버 주소 설정
    private final String URL = "jdbc:oracle:thin:@localhost:0000:XE";

    //드라이버 등록
    public BoardDAO() {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            //reflection(클래스 이름을 등록하면 모든 정보를 처리할 수 있다.)
            //ex.변수값 주입, 메서드 호출, 생성자 제어, 매개변수 확인 등 
            //=> Dependency Injection이라고 함
            //Spring이 클래스를 관리해 주는것임!
        } catch (Exception ex) {}
    }
    //오라클 연결
    public void getConnection() {
        try {
            conn = DriverManager.getConnection(URL, "user", "0000");
            //SQL Plus에 conn/username/pwd 입력하면 연결되는데 이 처리를 해 주는 것임.
        } catch (Exception ex) {}
    }
    //오라클 닫기
    public void disConnection() {
        try {
            if(ps != null)
                ps.close();
            if(conn != null)
                conn.close(); //SQL Plus에 exit하는거랑 마찬가지
        } catch (Exception ex) {}
    } //여기까지는 JDBC 쓰는거는 다 동일하다!
}

 

2. 로그인 처리

sql문을 실행시킬 때 "?"을 포함시키면, 이후에 사용자에게 받은 값을 그 위치에 넣어줄 수 있다.

PreparedStatement 객체의 메서드인 setString/setInt 등을 활용한다.

public String isLogin(String id, String pwd) {
   //입력된 id와 pwd가 DB에 저장되어 있다 아니다를 판단해서 결과를 리턴해줘야 한다.
   //NOID, NOPWD, OK
   String result = "";
   try {
      //1. 연결
      getConnection();
      
      //2. SQL문장 전송
      //2-1. ID의 존재 여부 확인
      String sql = "SELECT COUNT(*) " //공백주는거 잊지마셈
         +"FROM boardMember " 
         +"WHERE id=?"; 
         //count(*)가 0이면 X, 1이면 O! 중복체크, 로그인, 검색 결과 등에 사용
      ps = conn.prepareStatement(sql);
      ps.setString(1, id);
      ResultSet rs = ps.executeQuery();
      //SQL문을 실행하고 나면 커서 위치가 바뀜! 
      //next()로 데이터를 읽어올 수 있는 곳으로 커서 위치 변경
      rs.next(); 
      int count = rs.getInt(1);
      rs.close();
      //2-2. 처리~
      if(count == 0) {
         result = "NOID";
      } else {
         //ID가 있으니.. 비밀번호 검색
         sql = "SELECT pwd " +
            "FROM boardMember " +
            "WHERE id=?";
         ps = conn.prepareStatement(sql);
         ps.setString(1, id);
         rs = ps.executeQuery();
         rs.next();
         String db_pwd = rs.getString(1);
         rs.close();

         if(db_pwd.equals(pwd)) {
            result = "OK";
         } else {
            result = "NOPWD";
         }
      }
   } catch (Exception ex) {
      ex.printStackTrace();
   } finally {
      disConnection();
   }
   //3. 결과값 받아오기
   return result;
}

 

3. 목록 읽어오기

 

타입으로 List를 지정하고 생성자는 ArrayList를 쓰는 이유는 유연성을 위해서다.

더 자세한 내용은 여기 참고 → https://yoon-dailylife.tistory.com/7

public List < BoardVO > boardListData() {
   //게시글 여러 개를 한 번에 가져올것임.
   List < BoardVO > list = new ArrayList < BoardVO > ();
   try {
      //연결->SQL문장->오라클전송->결과값저장->List에 값채우기
      getConnection();
      String sql = "SELECT no, subject, name, regdate, hit " +
         "FROM freeboard " +
         "ORDER BY 1 DESC";
      ps = conn.prepareStatement(sql);
      ResultSet rs = ps.executeQuery();
      while(rs.next()) {
         //더 이상 읽을 데이터가 없을 때 rs.next()가 false를 리턴한다.
         BoardVO vo = new BoardVO();
         //"모아서" 저장하기 위해 굳이 VO의 리스트를 만든 것!
         vo.setNo(rs.getInt(1));
         vo.setSubject(rs.getString(2));
         vo.setName(rs.getString(3));
         vo.setRegdate(rs.getDate(4));
         vo.setHit(rs.getInt(5));
         list.add(vo);
      }
   } catch (Exception ex) {
      ex.printStackTrace();
   } finally {
      disConnection();
   }
   return list;
}

 

4. 글 작성 기능

Eclipse에서 SQL문을 불러와 실행할 때 PreparedStatement에 포함된 메서드를 이용한다.

실행할 SQL문이 SELECT문일 때는 executeQuery()를,

INSERT, UPDATE, DELETE문일 때는 executeUpdate()를 사용한다.

 

단순 조회인 SELECT문을 실행시킬 때와 달리 executeUpdate()는 자동으로

데이터베이스에 변경된 사항을 바로 적용시키는 commit을 포함한다.

필요에 따라 Connection 객체의 setAutoCommit()을 false로 처리해 줌으로써 오토커밋을 비활성시킨다.

당연히 commit() 메서드로 커밋을 수동으로 처리도 가능하다.

public void boardInsert(BoardVO vo) {
   try {
      //연결
      getConnection();
      //SQL문장
      String sql = "INSERT INTO freeboard(no, name, subject, content, pwd) " +
         "VALUES (" +
         "(SELECT NVL(MAX(no)+1,1) FROM freeboard)," //no는 sequence로
         +
         "?,?,?,?)";
      //오라클로 전송(=네트워크 서버에 보내는 것처럼)
      ps = conn.prepareStatement(sql);
      //"?"에 값을 채운다.
      ps.setString(1, vo.getName());
      ps.setString(2, vo.getSubject());
      ps.setString(3, vo.getContent());
      ps.setString(4, vo.getPwd());
      //실행
      ps.executeUpdate(); //commit이 포함되어 있음!!!
      //데이터가 변경되었을 때 commit이 실행된다. (insert, update, delete)
      //SELECT문일 때는 executeQuery였지만.. 위 3가지는 Update 사용
      conn.setAutoCommit(false); //이러면 오토커밋을 비활성화할 수 있다.
      conn.commit(); //이러면 커밋함.
   } catch (Exception ex) {
      ex.printStackTrace();
   } finally {
      disConnection();
   }
}

 

5. 글 수정 기능

public boolean boardUpdate(BoardVO vo) {
    boolean bCheck = false;
    try {
        getConnection();
        //우선 비밀번호 확인
        String sql = "SELECT pwd " +
            "FROM freeboard " +
            "WHERE no=?";
        ps = conn.prepareStatement(sql);
        ps.setInt(1, vo.getNo());
        ResultSet rs = ps.executeQuery();
        rs.next();
        String db_pwd = rs.getString(1);
        rs.close();

        if(db_pwd.equals(vo.getPwd())) {
            bCheck = true; //비밀번호가 맞음!
            //실제 수정 여기서 진행할 것임
            sql = "UPDATE freeboard SET " +
                "name=?, subject=?, content=? " +
                "WHERE no=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, vo.getName());
            ps.setString(2, vo.getSubject());
            ps.setString(3, vo.getContent());
            ps.setInt(4, vo.getNo());

            ps.executeUpdate();
        } else {
            bCheck = false; //비밀번호가 틀림.
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        disConnection();
    }
    return bCheck;
}

 

6. 글 삭제 기능

public void boardDelete(int no) {
    try {
        getConnection();
        String sql = "DELETE FROM freeboard WHERE no=?";
        ps = conn.prepareStatement(sql);
        ps.setInt(1, no);
        ps.executeUpdate();
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        disConnection();
    }
}

 

7. 글 검색 기능

public List < BoardVO > boardFind(String type, String fd) {
    List < BoardVO > list = new ArrayList < BoardVO > ();
    try {
        getConnection();
        //type = subject, name, content 중 하나
        String sql = "SELECT no,subject,name,regdate,hit " +
            "FROM freeboard "
            //+ "WHERE " + type + " LIKE '%" + fd + "%'";
            +"WHERE " + type + " LIKE '%'||?||'%'";
            //SQL문 속 문자열 결합을 이클립스에서 구현할 때는 주의.
        ps = conn.prepareStatement(sql);
        ps.setString(1, fd);
        ResultSet rs = ps.executeQuery();
        while(rs.next()) {
            //더 이상 읽을 데이터가 없을 때 rs.next()가 false를 리턴한다.
            BoardVO vo = new BoardVO();
            vo.setNo(rs.getInt(1));
            vo.setSubject(rs.getString(2));
            vo.setName(rs.getString(3));
            vo.setRegdate(rs.getDate(4));
            vo.setHit(rs.getInt(5));
            list.add(vo);
        }
        rs.close();
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        disConnection();
    }
    return list;
}

 

 

'부트캠프(END) > Oracle' 카테고리의 다른 글

JDBC 예제(JOIN 데이터 불러오기)  (0) 2022.06.30
DML, TCL  (0) 2022.06.28
DDL 예제  (0) 2022.06.28

댓글()