XML (23.05.29)

·2024년 1월 10일
0

Java

목록 보기
33/35
post-thumbnail

📝 XML

eXtensible Markup Language
단순화된 데이터 기술 형식

✏️ XML 사용 이유

Java는 코드가 한 글자라도 변환되면 다시 처음부터 전체 내용을 컴파일(이진 코드 번역)한다.
-> 비효율적

그런데, Java에 외부 파일을 읽어오는 변하지 않는 코드를 작성하면 컴파일을 다시 하지 않는다.
-> 컴파일을 다시 하지 않아도 외부 파일 내용이 변하면 자동으로 반영됨
-> 효율적

  • DB 연결 정보, SQL 내용은 빈번히 변화될 예정
    1) Java 코드에 직접 작성 -> 다시 컴파일 -> 실행 (비효율적)
    2) XML에 작성 -> 바로 실행 (다시 컴파일 X, 효율적)
    + (추가 효과) DB 정보, SQL 한 곳에 모아서 관리 (보기 좋고, 관리가 쉬움)

✏️ 주요 개념

💡 Property

속성(데이터)

💡 Properties

== Map<String, String>

* properties 컬렉션 객체

  1. <String, String>으로 Key, Value가 타입 제한된 Map
  2. XML 파일을 생성하고 읽어오는 데 특화

💡 comment

ctrl + shift + /
properties XML 파일 설명

💡 entry

Map의 Key, Value를 묶어서 부르는 명칭


예제

CreateXML 클래스

package edu.kh.jdbc.common;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class CreateXML {

	// XML(eXtensible Markup Language) : 단순화된 데이터 기술 형식
	
	
	// XML 사용하려는 이유
	// - DB 연결, SQL 같이 수정이 빈번한 내용을
	// 	 코드에 직접 작성하면 좋지 않음
	
	// 왜? Java == 컴파일 언어 -> 코드가 조금만 수정돼도 전체 컴파일 다시 함
	// 							-> 시간이 오래 걸림
	
	// 그런데, XML 외부 파일을 이용해서 XML 내용을 바꿔도
	// 	      Java에서 XML 파일을 읽어 오는 코드는 변하지 않음 -> 컴파일 X -> 시간 효율 상승
	
	public static void main(String[] args) {
		
		// XML은 K:V 형식 map, XML은 문자열만 저장
		
		// Map<String, String> == Properties
		
		// * Properties 컬렉션 객체 *
		// 1. <String, String>으로 Key, Value가 타입 제한된 Map
		// 2. XML 파일을 생성하고 읽어오는 데 특화
		
		Properties prop = new Properties();
		
		try {
			
			FileOutputStream fos = new FileOutputStream("driver.xml");
														// 파일 이름
			
			prop.storeToXML(fos, "DB Connection data"); // XML 파일 생성
			
		} catch (IOException e) {
			e.printStackTrace();
		} 
		
	}
}

LoadXML 클래스

package edu.kh.jdbc.common;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.InvalidPropertiesFormatException;
import java.util.Properties;

import oracle.jdbc.proxy.annotation.GetProxy;

public class LoadXML {

	public static void main(String[] args) {
		
		Properties prop = new Properties();
		// Key, Value가 String으로 제한된 Map
		
		try {
			prop.loadFromXML(new FileInputStream("driver.xml"));
			
			// Property : 속성(데이터)
			// prop.getProperty("driver") : XML에서 얻어온 값 중
			//								key가 "driver"인 인트리의 value를 얻어옴
			System.out.println("driver : " + prop.getProperty("driver"));
			
			// 외부 파일 미사용
			String str = "oracle.jdbc.driver.OracleDriver";
			System.out.println(str);
			
			// Java는 코드가 한 글자라도 변환되면
			// 다시 처음부터 전체 내용을 컴파일(이진 코드 번역)한다. --> 비효율적
			
			// 그런데, Java에 외부 파일을 읽어오는 변하지 않는 코드를 작성하면
			// 컴파일을 다시 하지 않는다. --> 효율적
			
			// 컴파일을 다시 하지 않아도 외부 파일 내용이 변하면 자동으로 반영됨
			
			// DB 연결 정보, SQL 내용은 빈번히 변화될 예정
			// 1) Java 코드에 직접 작성 -> 다시 컴파일 -> 실행 (비효율적)
			// 2) XML에 작성 -> 바로 실행(다시 컴파일 X, 효율적)
			//	  + (추가 효과) DB 정보, SQL 한 곳에 모아서 관리 (보기 좋고, 관리가 쉬움)

			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println(JDBCTemplate.getConnection());
		
	}
	
}

driver.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

<!-- 마크업 언어 주석 -->

<properties>
	
	<!-- comment : properties XML 파일 설명 -->
	<comment>DB Connection data</comment>
	
	<!-- entry : Map의 Key, Value를 묶어서 부르는 명칭 -->
	<entry key = "driver">oracle.jdbc.driver.OracleDriver</entry>
	
	<!-- 각자 계정 -->	
	<entry key = "url">jdbc:oracle:thin:@localhost:1521:xe</entry>
	
	<entry key = "user">ash_member</entry>
	
	<entry key = "password">member1234</entry>
	
</properties>

JDBCTemplate

-> 클래스 DB 연결, JDBC 자원 반환, 트랜잭션 제어 같은 반복적으로 사용되는 JDBC 관련 코드를 모아둔 클래스

package edu.kh.jdbc.common;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class JDBCTemplate {
	
	/* DB 연결, JDBC 자원 반환, 트랜잭션 제어 같은
	 * 반복적으로 사용되는 JDBC 관련 코드를 모아둔 클래스
	 * 
	 * getConnection() 메소드
	 * 
	 * close( Connection | Statement | ResultSet ) 메소드
	 *  --> PreparedStatement는 Statement의 자식이므로
	 *  	매개변수 다형성으로 한 번에 처리
	 *  
	 * commit(Connection)
	 * rollback(Connection)
	 * 
	 * 
	 */

	// 필드
	
	private static Connection conn; // 초기값 null
	// private static Connection conn = null; // 초기값 null
	
	// 메소드
	
	// DB 연결 정보를 담고 있는 Connection 객체 반환 메소드
	public static Connection getConnection() {
		
		try {
			
			// 계속 공용으로 사용되는 conn 변수에
			// 커넥션이 대입된 적 없거나 (null)
			// 또는 이전 커넥션이 있었으나 닫힌 경우
			// --> 새로운 커넥션이 필요한 상황!
			
			// 커넥션을 계속 닫고, 만들고... 닫고, 만들고를 반복
			// -> 프로그램 하나에 커넥션 1개만을 운용
			if(conn == null || conn.isClosed()) {
				
				Properties prop = new Properties();
				// K, V가 모두 String인 Map, XML 파일 입출력에 특화
				
				// driver.xml 파일 읽어 오기
				prop.loadFromXML(new FileInputStream("driver.xml"));
				
				// 커넥션 생성 준비
				String driver = prop.getProperty("driver");
				
				String url = prop.getProperty("url");
				String user = prop.getProperty("user");
				String password = prop.getProperty("password");
				
				// 커넥션 생성
				// 1) jdbc 드라이버 메모리 로드
				Class.forName(driver);
				
				// 2) DriverManager를 통해 Connection 생성
				conn = DriverManager.getConnection(url, user, password);
				
				// 3) 트랜잭션 제어를 위한 자동 커밋 비활성화
				conn.setAutoCommit(false);
				
			}
			
		}catch(Exception e) {
			e.printStackTrace();
		}
		
		return conn;
	}

	// close() 메소드 작성

	// Connection 반환 메소드
	public static void close(Connection conn) {
		try {
		
			// 참조하는 Connection이 있으면서 닫혀 있지 않은 경우
			if(conn != null && !conn.isClosed()) {
				// conn.isClosed() : 닫혀 있으면 true
				conn.close();
			}

		}catch(Exception e) {
			e.printStackTrace();
		}
		
	}
	
	// Statement(부모), PreparedStatement(자식) 반환 메소드(다형성 적용)
	public static void close(Statement stmt) {
		try {
		
			// 참조하는 Statement가 있으면서 닫혀 있지 않은 경우
			if(stmt != null && !stmt.isClosed()) {
				// stmt.isClosed() : 닫혀 있으면 true
				stmt.close();
			}

		}catch(Exception e) {
			e.printStackTrace();
		}
		
	}

	// ResultSet 반환 메소드
	public static void close(ResultSet rs) {
		try {
		
			// 참조하는 ResultSet이 있으면서 닫혀 있지 않은 경우
			if(rs != null && !rs.isClosed()) {
				// rs.isClosed() : 닫혀 있으면 true
				rs.close();
			}

		}catch(Exception e) {
			e.printStackTrace();
		}
		
	}
	
	// 트랜잭션 제어
	
	// commit 메소드
	public static void commit(Connection conn) {
		try {
		
			// 참조하는 Connection이 있으면서 닫혀 있지 않은 경우
			if(conn != null && !conn.isClosed()) {
				conn.commit();
			}

		}catch(Exception e) {
			e.printStackTrace();
		}
		
	}	
	
	// rollback 메소드
	public static void rollback(Connection conn) {
		try {
		
			// 참조하는 Connection이 있으면서 닫혀 있지 않은 경우
			if(conn != null && !conn.isClosed()) {
				conn.rollback();
			}

		}catch(Exception e) {
			e.printStackTrace();
		}
		
	}	
	
}
profile
풀스택 개발자 기록집 📁

0개의 댓글