[JAVA] Eclipse와 Oracle DB 연결(2) - XML파일에서 DB 정보 가져오기
Eclipse와 Oracle DB 연결(1)
1. Eclipse와 Oracle DB를 연결하기 위해 ojdbc.jar파일을 JDK 설치 디렉터리에 복사해주기 오라클을 설치한 후 ORACLE 경로에 가보면 ojdbc8.jar 파일이 있다. 그것을 JDK 설치 디렉토리/jre/lib/ext/에 복사해준..
hyokye0ng.tistory.com
지난 포스팅에 이어 외부의 XML 파일에서 데이터베이스 정보를 읽어 연결하는 방법에 대해 알아보자 ㅇ0ㅇ!!
Java Project를 export하여 사용할 때 DB정보가 코드 내부에 들어있다면 접속하고자 하는 데이터베이스가 바뀔 때마다 export된 파일을 다시 import하여 소스를 수정한 후 다시 export하여 실행해야 한다는 불편함이 존재한다.
데이터베이스 정보를 수정하여 export된 java 파일을 실행할 때마다 XML 파일만 수정하여 실행할 수 있도록 외부의 XML 파일에서 데이터베이스 정보를 읽어 연결해보자
1. XML 파일 생성하기
먼저 데이터베이스 정보를 가지고 있는 xml 파일을 생성한다. 이전 포스팅에서도 알 수 있듯이 HOST는 접속할 데이터베이스의 IP 주소(동일 pc라면 localhost), PORT는 리스너의 포트 번호(default값은 1521), SID는 데이터베이스의 service name을 의미한다.
2. XML 파일 읽어오기
나같은 경우는 export한 파일인 Viewer_size와 XML 파일이 같은 폴더에 존재한다고 가정한 후 config.xml 파일을 불러왔다.
(export한 .jar 파일 경로 추출 -> 현재 파일의 파일명 추출 -> .jar 경로에서 파일명 자르기 -> 최종 config_xml파일의 경로)
String path = Viewer_size.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); //현재 파일 경로
File jar = new File(path);
String File_name = jar.getName(); // 현재 파일의 파일명
String[] currDir = path.split(File_name); // 경로에서 파일명 자르기
File xml_file = new File(currDir[0] + "config.xml"); // 파일명 자른 디렉토리 경로에 존재하는 config.xml 파일 읽기
3. XML 파싱
불러온 config.xml 파일을 파싱하여 DB연결에 필요한 url 형태로 결합하였다.
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xml_file);
XPath xpath = XPathFactory.newInstance().newXPath();
String host = (String) xpath.compile("//config//HOST").evaluate(document, XPathConstants.STRING);
String port = (String) xpath.compile("//config//PORT").evaluate(document, XPathConstants.STRING);
String sid = (String) xpath.compile("//config//SID").evaluate(document, XPathConstants.STRING);
String url = "jdbc:oracle:thin:@//" + host + ":" + port + "/" + sid;
위의 코드에서 맨 마지막 줄의 url 결합하는 부분에서 계속 오류가 나 시간을 꽤나 잡아먹었다. 나의 인생 멘토 google님께 물어보고 또 물어본 결과 !!
SID를 사용하는 경우는 "jdbc:oracle:thin:@" + host + ":" + port + ":" + sid 요롷게,
Service_Name을 사용하는 경우는 "jdbc:oracle:thin:@" + host + ":" + port + "/" + sid 요롷게 해야한다는 것이었다. 그래서 열심히 이것저것 해봤다. 그렇제만 오류는 해결되지 않았다. 점점 열받으려던 찰나 멘토님께서 한 줄기 빛처럼
Service_Name을 사용하는 JSP에서는 "jdbc:oracle:thin:@//" + host + ":" + port + "/" + sid 요롷게 해야한다는 진리의 말씀을 주셨다. 그렇게 힘들고 힘들게 xml 파싱에 성공했다,,,, 휴~
4. ID, PASSWORD 입력받기
보안을 위해 id와 password는 사용자가 jar파일을 실행했을 때 입력받기로 하였다. id는 그냥 입력받으면 되지만 password는 소중한 개인정보이기 때문에 입력되는 문자가 보이지 않도록 암호화시켜야 하는 게 내 과제였다.
Console console = System.console();
Scanner scan = new Scanner(System.in);
System.out.println("Enter user ID: ");
String user = scan.nextLine();
System.out.println("Enter Password: ");
char[] charPass = console.readPassword(); //password 입력 암호화
String pwd = new String(charPass);
user ID는 누구나 다 아는 방법으로 그냥 단순하게 입력받았고 Password같은 경우는 java.io.Console 클래스의 readPassword() 메소드를 이용하여 처리했다.
readPassword 메소드는 키보드 입력 문자를 콘솔에 보여주지 않고 문자열을 읽는 메소드로 이클립스에서는 실행되지 않고 명령 프롬프트에서만 실행된다는 특징이 있다. 이클립스에서 실행할 경우 다음과 같은 'console' is null 이라는 오류가 생겨버린다 뿌에엥
5. DB 연결 완료 !!
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(url, user, pwd);
System.out.println("Database connect");
앞에서 XML 파일을 파싱하여 얻은 url 정보와 입력받은 user 정보를 이용하여 데이터베이스에 연결한다. 실행 결과로 "Database connect"가 나오면 정상적으로 연결된 것이다 !
DBConnection 전체 소스코드
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Scanner;
import java.io.File;
import java.io.Console;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
public class DBConnection {
public static Connection dbConn;
public static Connection getConnection() {
Connection conn = null;
try {
// EXPORT한 .jar 파일명: Viewer_size => 자신의 파일명 입력하면 됩니당
String path = Viewer_size.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); //현재 파일 경로
File jar = new File(path);
String File_name = jar.getName(); // 현재 파일의 파일명
String[] currDir = path.split(File_name); // 경로에서 파일명 자르기
File xml_file = new File(currDir[0] + "config.xml"); // 파일명 자른 디렉토리 경로에 존재하는 config.xml 파일 읽기
// XML 파싱
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xml_file);
XPath xpath = XPathFactory.newInstance().newXPath();
String host = (String) xpath.compile("//config//HOST").evaluate(document, XPathConstants.STRING);
String port = (String) xpath.compile("//config//PORT").evaluate(document, XPathConstants.STRING);
String sid = (String) xpath.compile("//config//SID").evaluate(document, XPathConstants.STRING);
String url = "jdbc:oracle:thin:@//" + host + ":" + port + "/" + sid;
// USER id, password 입력
Console console = System.console();
Scanner scan = new Scanner(System.in);
System.out.println("Enter user ID: ");
String user = scan.nextLine();
System.out.println("Enter Password: ");
char[] charPass = console.readPassword(); //password 입력 암호화
String pwd = new String(charPass);
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(url, user, pwd);
System.out.println("Database connect");
} catch (ClassNotFoundException cnfe) {
System.out.println("DB Driver loading fail: " + cnfe.toString());
} catch (SQLException sqle) {
System.out.println("DB Connect fail: :" + sqle.toString());
} catch (Exception e) {
System.out.println("Unknown error");
e.printStackTrace();
}
return conn;
}
}
Eclipse와 Oracle DB연결을 성공적으로 완료하였으니, 이제 Java 소스코드에서 Oracle DB의 데이터를 가져와서 사용해보자!
TEST 전체 소스코드
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Test
{
public static void main(String args[])
{
Connection conn = null; // DB 세션 객체
PreparedStatement pstm = null; // SQL 객체
ResultSet rs = null; // 쿼리문의 반환값 객체
try {
String quary = "SELECT s_doc_no FROM ENGINEER.DOCUMENT WHERE rownum <= 5";
conn = DBConnection.getConnection(); // DBConnection 클래스의 연결상태를 conn에 저장
pstm = conn.prepareStatement(quary); // DB에 quary 전송
rs = pstm.executeQuery(); // quary 결과 rs에 저장
System.out.println("S_DOC_NO DESCRIPTION");
System.out.println("=======================");
while(rs.next()){ // rs에서 다음 데이터가 존재한다면 반복 실행
String s_dwg_no = rs.getString(1);
String description = rs.getString(1);
String result = s_dwg_no+" "+description;
System.out.println(result);
}
// finally문에서도 DB연결을 종료해 줄 것이지만 TRY문 내에서도 닫아주는 게 좋음
rs.close();
pstm.close();
conn.close();
} catch (SQLException sqle) { // Quary 오류
System.out.println("QUARY ERROR");
sqle.printStackTrace();
}finally{ // DB 연결 종료
try{
if ( rs != null ){rs.close();}
if ( pstm != null ){pstm.close();}
if ( conn != null ){conn.close(); }
}catch(Exception e){
throw new RuntimeException(e.getMessage());
}
}
}
}