공적's life

4-4 JDBC -1 본문

Programing/Java programing

4-4 JDBC -1

melpis 2010. 8. 10. 21:44

이제 실제로 DataBase라는 것을 사용해 보도록 하죠. DataBase에 대한 설명은 다음에 하도록 하고

 

오늘은 Java Database Connectivity 즉 JDBC에 대해서 살짝 알아 보고 사용해 보도록 하죠.

 

전에 제가 만들었던 DataBase와 유사하게 동작합니다. 특정한 문자를 주면 등록, 조회, 수정, 삭제

 

즉 C.R,U.D를 하게 됩니다. 간단하죠? 꽤나 오랜 시간 동안 발전해 왔기 때문에 우리는 그것에 대한

 

규칙을 지켜야 합니다. SQL(Structured Query Language)이라는 언어를 사용합니다. 이것도 다음 기회에

 

DataBase를 설명할 때 다시 하도록 하고, 오늘은 그 사용법에 대해서 해보도록 하죠. 일단

 

database management system를 설치해 보도록 하죠. DataBase를 사용하고 관리하는 시스템입니다.

 

흔히 DataBase라고 합니다. 설치법은 간단하게 오라클XE버전을 깔아 보도록 하죠.

 

http://www.oracle.com/technetwork/database/express-edition/downloads/102xewinsoft-090667.html

 

위에 주소로 가서 OracleXEUniv.exe를 받아서 설치합니다.

 

설치과정은 그냥 다음만 누르시면 됩니다. 비밀번호만 넣어주시고요. 그래서 설명하지 않겠습니다.

 

GUI도 있지만 혹시 사용 못할 경우가 있기 때문에 sqlplus라는 것을 사용해 보도록 하죠.

 

일단 도스창을 띄워서(실행->cmd or 윈도우키+R ->cmd) sqlplus라고 치시면

 

접속이 됩니다. 일단 계정부터 생성해야겠죠?

 

사용자명에 /as sysdba라고 치시면 됩니다.

 

그런 다음에 create user user00 identified by user00 를 치시면 됩니다

 

밑줄 친 부분은 첫 번째 것이 아이디 두 번째 것이 패스워드 입니다.

 

그런 후에 권한을 줘야지만 데이터를 저장 삭제 수정 등록 할 수 잇는데

 

Grant connect, resource to user00 을 치시면 됩니다 .

 

Connect는 접속 할 수 있는 권한, resource는 생성 할 수 있는 권한입니다.

 

그리고 나서 commit; 을 해주시면 됩니다.

 

그런 후에 conn user00/user00 을 치시면 user00으로 접속이 됩니다.

 

이제 table을 생성해 보도록 하죠.

 

create table TB_BOARD(

SEQ number(20) not null primary key,

TITLE varchar2(600) not null,

CONTENT varchar2(2000) not null,

REGIST_DATE date not null,

HIT number(10) not null);

 

이렇게 치시면 됩니다. 나중에 좀더 자세히 다루어 보죠.

 

혹시 중간에 오타가 나서 실행이 안될 경우에는 ed라는 명령어를

 

메모장이 뜹니다. 그럼 거기에 수정하시고 나서 저장 후에 닫으시고

 

/ 를 누른 후에 엔터를 치면 저장했던 sql문이 실행이 됩니다.

 

역시나 여기까지 완료하고 나서 commit 을 해주시면 됩니다.

 

여기까지 준비가 완료 됐습니다. 이제 실제로 JDBC를 이용해서

 

데이터를 넣거나 삭제하거나 수정하고 가져와 볼까요?

 

생각보다 어렵지 않습니다. 제가 전에 network를 이용한 database를 작성했을 때

 

사실 이것을 노리고 작성했기 때문에 비슷하게 쓸 수 있습니다. 그럼 이왕 말이 나온 김에

 

해보도록 하죠.

 

C:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib

 

일단 위에서 next만 하셨다면 이경로에 있을 겁니다. 무엇이 있느냐 두 개에 파일이 존재 할 것 입니다.

 

그 이름은 ojdbc14.jar, ojdbc14_g.jar 가 있을 겁니다. 그 중에서 ojdbc14.jar파일을 일단 복사한 후에

 

이클립스에서 새로운 폴더를 만들어 주신 후에(프로젝트에서 마우스 오른쪽 클릭->폴더 ->lib으로 이름 설정)

 

거기에 다가 넣어 주시면 됩니다. 무엇을 ojdbc14.jar를 요!

 

그 다음에 lib폴더로 가서 ojdbc14.jar를 오른쪽 마우스 클릭 하신 후에 Build Path -> Add to Build Path를 선택하시면 됩니다.

 

 

코딩은 전에 작성했던 BoardManger 수정해서 작성하였습니다. 일단 등록 메소드를 살펴 볼까요?

// 문서 등록

    public void registDocument(String[] outputData) {

        // 1.1 제목 추출

        String userInputTitle = outputData[1];

        // 1.2 내용 추출

        String userInputContent = outputData[2];

        // 2. 유효성 검사

        if (userInputTitle.length() < 1 && userInputTitle.length() > 600) {

            return;

        }

        if (userInputContent.length() < 1 && userInputContent.length() > 2000) {

            return;

        }

        try {

            //3.1 드라이버 로딩

            Class.forName("oracle.jdbc.driver.OracleDriver");

        } catch (ClassNotFoundException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        try {

            //3.2 연결하기

            Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","user00","user00");

            //3.3 sql문 준비하기

            String sql ="insert into TB_BOARD(SEQ, TITLE, CONTENT, REGIST_DATE, HIT)";

                sql+="values(1,'"+userInputTitle+"', '"+userInputContent+"', sysdate, 0) ";

            //3.4 prepardStatement에 sql넣기

            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            //3.5 실행

            preparedStatement.executeUpdate();

            //3.6 닫기

            preparedStatement.close();

            connection.close();

        } catch (SQLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        

        // 4. 결과 출력

        System.out.println("등록 완료");

 

    }

전에 작성 했었던 것과 그다지 차이가 없죠? 항상 위에 절차대로 하시면 문제가 없겠습니다.

 

그렇지만 전에는 자동으로 문서번호를 가져왔는데 이번에는 수동으로 해야 하는 건가요?

 

무지 불편해요! 라는 불평을 늘어 놓으실 것 같아서 준비했습니다. 우리가 사용하는

 

데이터베이스가 오라클이기 때문에 Sequence라는 것이 있습니다. 그냥 간단히 자동으로

 

번호를 증가 시켜주는 것이지요. 사용해볼까요?

 

create sequence SEQ_TB_BOARD start with 1 increment by 1 maxvalue 9999999 nocycle nocache

 

이렇게 만드시면 됩니다. 일단 SEQ_TB_BOARD 이것은 이름이고, start with는 시작번호

 

increment by 증가 값입니다. 1로 지정했으니 1씩 증가 하겠죠?

maxvalue 9999999 nocycle nocache maxvalue는 최대값 nocycle은 순환하지 않음 nocahe는 캐쉬 사용안함

 

입니다. 이제 사용해 보도록 하죠.

 

//3.3 sql문 준비하기

            String sql ="insert into TB_BOARD(SEQ, TITLE, CONTENT, REGIST_DATE, HIT)";

                sql+="values(SEQ_TB_BOARD.NEXTVAL,'"+userInputTitle+"', '"+userInputContent+"', sysdate, 0) ";

 

이렇게 쓰시면 됩니다. 간단하죠?

 

이제 남은 메소드를 마저 작성 해보도록 하죠.

 

근데 중복되는 문자 들이 있네요. 예를 들어서 드라이버 로딩과 데이터베이스 접속 부분입니다.

 

그래서 그 문자들은 위쪽으로 빼도록 하죠.

 

나머지도 그다지 차이점을 찾아 볼 수가 없군요. 하지만 단 한가지 데이터를 조회하는 부분에서

 

조금 다르게 사용하는 군요. 한번 살펴 볼까요?

 

// 문서 상세 보기

public void viewDocument(String[] outputData){

    //1. 사용자가 입력한 문서 번호 가져오기

    String userInputSeq = outputData[1];

    //1.1 변환

    int parameterSeq = Integer.parseInt(userInputSeq);

    //2. 유효성 검사

    if(parameterSeq<0){

        return;

    }

    

    try {

        //3.1 드라이버 로딩

        Class.forName(DRIVER_NAME);

    } catch (ClassNotFoundException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    }

    Map<String,String> data = null;

    

    try {

        //3.2 연결하기

        Connection connection = DriverManager.getConnection(DB_URI,DB_USER_NAME,DB_USER_PASSWORE);

        //3.3 sql문 준비하기

        String sql =" select SEQ, TITLE, CONTENT, REGIST_DATE, HIT ";

        sql+=" from TB_BOARD ";

        sql+=" where SEQ="+parameterSeq;

        //3.4 prepardStatement에 sql넣기

        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //3.5 실행

        ResultSet resultSet =preparedStatement.executeQuery();

        //3.6 결과값 매핑

        if(resultSet.next()){

            data = new HashMap<String, String>();

            data.put("SEQ", String.valueOf(resultSet.getInt("SEQ")));

            data.put("TITLE",resultSet.getString("TITLE"));

            data.put("CONTENT",resultSet.getString("CONTENT"));

            data.put("REGIST_DATE",resultSet.getDate("REGIST_DATE").toString());

            data.put("HIT",String.valueOf(resultSet.getInt("HIT")));

        }

        //3.7 닫기

        resultSet.close();

        preparedStatement.close();

        connection.close();

    } catch (SQLException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    }

    //4. 결과 출력

    System.out.println("글번호 : " +data.get("SEQ"));

    System.out.println("제목 : " +data.get("TITLE"));

    System.out.println("등록일 : " +data.get("REGIST_DATE"));

    System.out.println("조회수 : " +data.get("HIT"));

    System.out.println("내용 : " +data.get("CONTENT"));

    

}

 

preparedStatement에서 executeUpdate가 아닌 executeQuery를 사용하죠?

 

이점이 데이터를 조회 할 때 다른 점입니다. 반환값으로 ResultSet을 줍니다. 한가지 재미난점은

 

타입에 맞게 사용해 된다는 점입니다. 만약에 SEQ라는 숫자형 이라면 숫자로 맞추어 줘야 한다는 거죠.

 

혹시 제 블로그를 잘 보신 분 이라면 이러한 의문을 가지 실수 있습니다. 데이터베이스와 통신은 문자열로 해서

 

문자열로 받는데 왜 굳이 저렇게 타입으로 맞추어 줘야 하는가? 라는 의문이 생길 수도 있습니다.

 

하지만 우리가 실제로 사용할 때는 어차피 변환을 해야 합니다. 그것을 조금 더 편하게 해주는 것뿐입니다.

 

만약에 저렇게 제공하지 않는다면 위에 예처럼 문자로 전부 변환 해야 하고 혹시 잘못해서 실수를 하게 되면

 

오류가 나올 수도 있겠죠?

 

사용법은 간단하게 위에 예처럼 사용하시면 됩니다. 실제로 코드를 보시면 이해가 잘 되실 것입니다.

 

아무래도 한번 쪼개서 글을 써야겠군요. 두 번째 시간에는 조금 더 편한 방법을 사용해 보도록 할까요?

 

여담이지만 사실 테이블 생성을 할 때 GUI를 이용하려고 했는데 이상하게 오류가 나는 바람에 급히

 

SqlPlus를 사용하게 되었습니다. 뭐 다양한 방법으로 익혀 보는 것도 좋습니다.

 

툴을 사용하면 더욱 편하게 사용 할 수 있습니다. 하지만 그것을 사용 할 수 없을 때도 있습니다.

 

예를 들어서 라이선스 문제로 회사나 기관에서 사용금지 한다면 어떻게 하시겠습니까?

 

그러한 의미로 여러 가지로 익혀두시면 나중에 몸과 머리가 편해 질 겁니다. 다음에는 GUI를 이용해서

 

해보도록 하고, 다른 툴도 사용해 보도록 할게요!

 

 

package com.tistory.melpis.board;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BoardManager {
	private final String DRIVER_NAME="oracle.jdbc.driver.OracleDriver";
	private final String DB_URI="jdbc:oracle:thin:@localhost:1521:XE";
	private final String DB_USER_NAME="user00";
	private final String DB_USER_PASSWORE="user00";
	
	public BoardManager(){
	}
	
	// 문서 등록 폼
	public void registDoumentForm() {

		// 1. 등록 폼출력
		System.out.println("제목: ");
		System.out.println("내용: ");

	}
	// 문서 등록
	public void registDocument(String[] outputData) {
		// 1.1 제목 추출
		String userInputTitle = outputData[1];
		// 1.2 내용 추출
		String userInputContent = outputData[2];
		// 2. 유효성 검사
		if (userInputTitle.length() < 1 && userInputTitle.length() > 600) {
			return;
		}
		if (userInputContent.length() < 1 && userInputContent.length() > 2000) {
			return;
		}
		try {
			//3.1 드라이버 로딩
			Class.forName(DRIVER_NAME);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		try {
			//3.2 연결하기 
			connection = DriverManager.getConnection(DB_URI,DB_USER_NAME,DB_USER_PASSWORE);
			//3.3 sql문 준비하기
			String sql ="insert into TB_BOARD(SEQ, TITLE, CONTENT, REGIST_DATE, HIT)";
				sql+="values(SEQ_TB_BOARD.NEXTVAL, '"+userInputTitle+"', '"+userInputContent+"', sysdate, 0) ";
			//3.4 prepardStatement에 sql넣기
			preparedStatement = connection.prepareStatement(sql);
			//3.5 실행
			preparedStatement.executeUpdate();
			//3.6 닫기
			preparedStatement.close();
			connection.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// 4. 결과 출력
		System.out.println("등록 완료");

	}
	
	// 문서 상세 보기 
	public void viewDocument(String[] outputData){
		//1. 사용자가 입력한 문서 번호 가져오기
		String userInputSeq = outputData[1];
		//1.1 변환
		int parameterSeq = Integer.parseInt(userInputSeq);
		//2. 유효성 검사
		if(parameterSeq <=0){
			return;
		}
		
		try {
			//3.1 드라이버 로딩
			Class.forName(DRIVER_NAME);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Map data = null;
		
		try {
			//3.2 연결하기 
			Connection connection = DriverManager.getConnection(DB_URI,DB_USER_NAME,DB_USER_PASSWORE);
			//3.3 sql문 준비하기
			String sql =" select SEQ, TITLE, CONTENT, REGIST_DATE, HIT ";
			sql+=" from TB_BOARD ";
			sql+=" where SEQ=  "+parameterSeq;
			//3.4 prepardStatement에 sql넣기
			PreparedStatement preparedStatement = connection.prepareStatement(sql);
			
			//3.5 실행
			ResultSet resultSet =preparedStatement.executeQuery();
			//3.6 결과값 매핑
			if(resultSet.next()){
				data = new HashMap();
				data.put("SEQ", String.valueOf(resultSet.getInt("SEQ")));
				data.put("TITLE",resultSet.getString("TITLE"));
				data.put("CONTENT",resultSet.getString("CONTENT"));
				data.put("REGIST_DATE",resultSet.getDate("REGIST_DATE").toString());
				data.put("HIT",String.valueOf(resultSet.getInt("HIT")));
			}
			//3.7 닫기
			resultSet.close();
			preparedStatement.close();
			connection.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//4. 결과 출력
		System.out.println("글번호 : " +data.get("SEQ"));
		System.out.println("제목  : "  +data.get("TITLE"));
		System.out.println("등록일 : " +data.get("REGIST_DATE"));
		System.out.println("조회수 : " +data.get("HIT"));
		System.out.println("내용 : "  +data.get("CONTENT"));
		
	}
	

	public void viewDocumentList(){
		
		try {
			//3.1 드라이버 로딩
			Class.forName(DRIVER_NAME);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
		List> dataList = new ArrayList>();
		try {
			//3.2 연결하기 
			Connection connection = DriverManager.getConnection(DB_URI,DB_USER_NAME,DB_USER_PASSWORE);
			//3.3 sql문 준비하기
			String sql =" select SEQ, TITLE, CONTENT, REGIST_DATE, HIT ";
			sql+=" from TB_BOARD ";
			//3.4 prepardStatement에 sql넣기
			PreparedStatement preparedStatement = connection.prepareStatement(sql);
			//3.5 실행
			ResultSet resultSet =preparedStatement.executeQuery();
			//3.6 결과값 매핑
			while(resultSet.next()){
				Map data = new HashMap();
				data.put("SEQ", String.valueOf(resultSet.getInt("SEQ")));
				data.put("TITLE",resultSet.getString("TITLE"));
				data.put("CONTENT",resultSet.getString("CONTENT"));
				data.put("REGIST_DATE",resultSet.getDate("REGIST_DATE").toString());
				data.put("HIT",String.valueOf(resultSet.getInt("HIT")));
				dataList.add(data);
			}
			//3.7 닫기
			resultSet.close();
			preparedStatement.close();
			connection.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 4. 결과 출력
		for(Map data:dataList){
			System.out.println("글번호 : " +data.get("SEQ"));
			System.out.println("제목  : "  +data.get("TITLE"));
			System.out.println("등록일 : " +data.get("REGIST_DATE"));
			System.out.println("조회수 : " +data.get("HIT"));
			System.out.println("내용 : "  +data.get("CONTENT"));
		}

	}

	public void deleteDocument(String[] outputData) {
		//1. 사용자가 입력한 문서 번호 가져오기
		String userInputSeq = outputData[1];
		//1.1 변환
		int parameterSeq = Integer.parseInt(userInputSeq);
		//2. 유효성 검사
		if(parameterSeq<=0){
			return ;
		}
		
		try {
			//3.1 드라이버 로딩
			Class.forName(DRIVER_NAME);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			//3.2 연결하기 
			Connection connection = DriverManager.getConnection(DB_URI,DB_USER_NAME,DB_USER_PASSWORE);
			//3.3 sql문 준비하기
			String sql =" delete from TB_BOARD ";
			sql+=" where SEQ= "+parameterSeq;
			//3.4 prepardStatement에 sql넣기
			PreparedStatement preparedStatement = connection.prepareStatement(sql);
			//3.5 실행
			preparedStatement.executeUpdate();
			//3.6 닫기
			preparedStatement.close();
			connection.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//4. 결과 출력
		System.out.println("삭제 되었습니다");

	}

	public void editDocumentForm(String[] outputData) throws ParseException {
		//1. 사용자가 입력한 문서 번호 가져오기
		String userInputSeq = outputData[1];
		//1.1 변환
		int parameterSeq = Integer.parseInt(userInputSeq);
		//2. 유효성 검사
		if(parameterSeq<=0){
			return;
		}
		
		try {
			//3.1 드라이버 로딩
			Class.forName(DRIVER_NAME);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Map data = null;
		
		try {
			//3.2 연결하기 
			Connection connection = DriverManager.getConnection(DB_URI,DB_USER_NAME,DB_USER_PASSWORE);
			//3.3 sql문 준비하기
			String sql =" select SEQ, TITLE, CONTENT, REGIST_DATE, HIT ";
			sql+=" from TB_BOARD ";
			sql+=" where SEQ= "+parameterSeq;
			//3.4 prepardStatement에 sql넣기
			PreparedStatement preparedStatement = connection.prepareStatement(sql);
			//3.5 실행
			ResultSet resultSet =preparedStatement.executeQuery();
			//3.6 결과값 매핑
			if(resultSet.next()){
				data = new HashMap();
				data.put("SEQ", String.valueOf(resultSet.getInt("SEQ")));
				data.put("TITLE",resultSet.getString("TITLE"));
				data.put("CONTENT",resultSet.getString("CONTENT"));
				data.put("REGIST_DATE",resultSet.getDate("REGIST_DATE").toString());
				data.put("HIT",String.valueOf(resultSet.getInt("HIT")));
			}
			//3.7 닫기
			resultSet.close();
			preparedStatement.close();
			connection.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//4. 결과 출력
		System.out.println("글번호 : " +data.get("SEQ"));
		System.out.println("제목  : "  +data.get("TITLE"));
		System.out.println("등록일 : " +data.get("REGIST_DATE"));
		System.out.println("조회수 : " +data.get("HIT"));
		System.out.println("내용 : "  +data.get("CONTENT"));
		
	}

	public void editDocument(String[] outputData) {
		//1.1 번호 추출
		String userInputSeq = outputData[1];
		//1.2 제목 추출  
		String userInputTitle = outputData[2];
		//1.3 내용 추출
		String userInputContent = outputData[3];
		//1.4 변환
		int parameterSeq = Integer.parseInt(userInputSeq);
		//2. 유효성검사
		if(parameterSeq<=0){
			return ;
		}
		if (userInputTitle.length() < 1 && userInputTitle.length() > 600) {
			return;
		}
		if (userInputContent.length() < 1 && userInputContent.length() > 2000) {
			return;
		}
		try {
			//3.1 드라이버 로딩
			Class.forName(DRIVER_NAME);
		} catch (ClassNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		try {
			//3.2 연결하기 
			Connection connection = DriverManager.getConnection(DB_URI,DB_USER_NAME,DB_USER_PASSWORE);
			//3.3 sql문 준비하기
			String sql =" update TB_BOARD set ";
			sql+=" TITLE = '"+userInputTitle+"' , ";
			sql+=" CONTENT = '"+userInputContent+"' , ";
			sql+=" REGIST_DATE = sysdate ";
			sql+=" where SEQ= "+parameterSeq;
			//3.4 prepardStatement에 sql넣기
			PreparedStatement preparedStatement = connection.prepareStatement(sql);
			//3.5 실행
			preparedStatement.executeUpdate();
			//3.6 닫기
			preparedStatement.close();
			connection.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		//4. 결과 출력
		System.out.println("수정완료 하였습니다");

	}
	
}

'Programing > Java programing' 카테고리의 다른 글

4-6 XML  (0) 2010.08.13
4-5 JDBC-2  (0) 2010.08.10
4-3 DataBase network  (0) 2010.08.07
4-2 NetWork  (0) 2010.08.03
4-1 I.O and File  (0) 2010.07.31