230816 TIL Chapter 27. JDBC

최규연·2023년 8월 16일
0

TIL

목록 보기
29/57

JDBC 2번쩨 시간!
저번 시간에 이어서 JDBC를 나갔는데 저번 시간엔 SELECT을 통해 값을 DB에서 가져왔다면 이번엔 INSERT를 사용해 DB에 새로운 값을 넣는 것과 XML을 사용하는 법을 배웠다.

XML

먼저 XML부터 작성해보면
eXtensible Markup Languege의 약자로 단순화된 데이터 기술 형식으로 XML에 저장되는 데이터 형식은 Key : Value 형식(Map)이다
-> Key , Value 모두 String(문자열) 형식이다.

XML 파일을 읽고, 쓰기 위한 IO 관련 클래스가 필요하다

Properties 컬렉션 객체

  • Map의 후손 클래스
  • Key , Value 모두 Stirng(문자열 형식)
  • XML 파일을 읽고, 쓰는데 특화된 메서드 제공

XML 파일 만들기

try {
			
	Scanner sc = new Scanner(System.in);
			
	// Properties 객체 생성
	Properties prop = new Properties();
			
	System.out.print("생성할 파일 이름 : ");
	String fileName = sc.nextLine();
			
	// FileOutputStream 생성
	FileOutputStream fos = new FileOutputStream(fileName + ".xml");
			
	// Properties 객체를 이용해서 XML 파일 생성
	prop.storeToXML(fos, fileName);
			
	System.out.println(fileName + ".xml 파일 생성 완료");
			
			
} catch(Exception e) {
	e.printStackTrace();
}

XML 파일 읽어오기

Properties, FrilInputStream를 사용해서 XML 파일을 읽어오는 방법을 알아보자

먼저 왜 XML 파일을 이용해서 DB와 연결 정보를 읽어오는게 좋은지 보면

  1. 코드 중복 제거
  2. 별도 관리 용도
  3. 재 컴파일을 진행하지 않기 위해 !!!
    코드 길이가 길수록 컴파일에서 소요되는 시간이 크기 때문에 코드 수정으로 인한 컴파일 소요시간을 없앨 수 있다.
    ( 파일의 내용을 읽어오는 코드만 작성해두면 Java코드 수정 없이, 파일 내용만 수정하면 재 컴파일은 수행되지 않는다.)
  4. XML 파일에 작성된 문자열 형태를 그대로 읽어오기 때문에 SQL 작성시 조금 더 편리해진다.
try {
			
	Properties prop = new Properties();
			
	// driver.xml 파일을 읽어오기 위한 InputStream 객체 생성
	FileInputStream fis = new FileInputStream("driver.xml");
			
			
	// 연결된 diver.xml 파일에 있는 내용을 모두 읽어와
	// Properties 객체에 K:V형식으로 저장
	prop.loadFromXML(fis);
			
	System.out.println(prop);
			
	// Property : 속성(데이터)
			
	// prop.getProperty("key"); : key가 일치하는 속성을 얻어옴
			
	String driver = prop.getProperty("driver");
	String url = prop.getProperty("url");
	String user = prop.getProperty("user");
	String password = prop.getProperty("password");
			
	Class.forName(driver);
	Connection conn = DriverManager.getConnection(url, user, password);
			
	System.out.println(conn);
    
} catch(Exception e) {
	e.printStackTrace();
}

JDBC INSERT

위 XML파일을 만든 이유인 즉 SQL을 XML로 다룰 예정이라 만들었고 이렇게 사용하면 위 장점으로 설명된다.

VO,Service,DAO,Run,XML 이렇게 5가지를 사용할 예정이고 아주 간략하게 보면 VO는 사용할 객체만 정리해 놓고
Run -> Service -> DAO -> XML -> DAO -> Service -> Run 이런식으로 갔다 돌아오고 콘솔창에 결과값이 나온다.
이번엔 INSERT를 사용하니 DB엔 새로운 값이 테이블에 들어가고 리턴값으론 0 혹은 1로 나온다.

VO는 지금까지 해온거와 다른게 없기에 넘어가서 위에 간략하게 본 순서로 Run, Service, DAO, XML 순으로 보겠다.

코드를 한 화면에 다 놓고 이동하는 길을 보면 이해가 쉬우니 이 글을 참고로 코드를 작성하고 큰 그림을 한번에 보는게 좋다.

Run Class

TestService service = new TestService();
		
// TB_test 테이블에 INSERT 수행
TestVO vo1 = new TestVO(1, "제목1", "내용1");
		
// TB_TEST 테이블에 insert를 수행하는 서비스 메서드를 호출 후
// 결과 반환 받기
try {
	int result = service.insert(vo1); // 1 , 0
			
	if(result > 0) {
		System.out.println("insert 성공");
	} else {
		System.out.println("insert 실패");
	}
			
} catch(SQLException e) {
	System.out.println("SQL 수행 중 오류 발생");
	e.printStackTrace();
}

TB_test 테이블은 미리 만들었고 위 코드는 메인메서드 안에서 실행시킨다.

Service Class

//  import static 구문
// -> static이 붙은 필드, 메서드를 호출할 때
//		클래식명을 생략할 수 있게 해주는구문
import static edu.kh.jdbc.common.JDBCTemplate.*;

import java.sql.Connection;
import java.sql.SQLException;

import edu.kh.jdbc.model.dao.TestDAO;
import edu.kh.jdbc.model.vo.TestVO;

public class TestService {
	// Service : 비즈니스 로직(데이터 가공, 트랜잭샨 제어) 처리
	// -> 실제 프로그램이 제공하는 기능을 모아놓은 클래스
	
	// 하나의 service 메서드에서 n개의 DAO 메서드를 호출하여
	// 이를 하나의 트랜잭션 단위로  취급하여
	// 한번에 commit,rollback을 수행할 수 있다.

	private TestDAO dao = new TestDAO();
	
	public int insert(TestVO vo1) throws SQLException {

		// 커넥션 생성
		Connection conn = getConnection();
		
		// DAO 메서드 호출하여 수행 후 결과 반환받기
		// -> Service에서 생성한 Connection 객체를 반드시 같이 전달!
		int result = dao.insert(conn, vo1);
		
		// 트랜잭션 제어
		if(result > 0) commit(conn);
		else			rollback(conn);
		
		// 커넥션 반환
		close(conn);
		
		// 결과 반환
		return result;
		
	}

먼저 import static 구문과 커넥션,트랜잭션 제어를 중점적으로 봐야한다.

DAO Class

DAO ( Data Access Object ) : 데이터가 저장된 DB에 접근하는 객체 / SQL 수행, 결과 반환 받는 기능을 수행한다.

	// JDBC 객체를 참조하기 위한 참조변수 선언
	private Statement stmt;
	private PreparedStatement pstmt;
	private ResultSet rs;
	
	
	// xml로 SQL을 다룰것이다. -> Properties 객체 사용
	private Properties prop;
	
	
	// 기본 생성자
	public TestDAO() {
		// TestDAO 객체 생성 시
		// test-query.xml 파일의 내용을 읽어와
		// Properties 객체에 저장
		
		try {
			prop = new Properties();
			prop.loadFromXML(new FileInputStream("test-query.xml"));
		} catch(Exception e) {
			e.printStackTrace();
		}
		
	}
	
	
	public int insert(Connection conn, TestVO vo1) throws SQLException {
		
		// 1. 결과 저장용 변수 선언
		int result = 0;
		
		try {

			// 2. SQL 작성(test-query.xml에 작성된 SQL얻어오기)
			String sql = prop.getProperty("insert");
			// INSERT INTO TB_TEST
			// VALUES(?, ?, ?)

			// 3. PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);

			// 4. 위치 홀더(?)에 알맞은 값 세팅 -> 위치홀더는 물음표임
			pstmt.setInt(1, vo1.getTestNo());
			pstmt.setString(2, vo1.getTestTitle());
			pstmt.setString(3, vo1.getTestContent());

			// 5. SQL(INSERT) 수행 후 결과 반환받기
			result = pstmt.executeUpdate(); // -> DML 수행, 반영된 행의 개수(int) 반환


		} finally {
			// 6. 사용한 JDBC 객체 자원 반환
			close(pstmt);
		}

		//7. SQL 수행 결과 반환
		return result;


	}

XML 코드 확인

<properties>
	<comment>test-query</comment>
	
	<entry key = "insert">
		INSERT INTO TB_TEST
		VALUES(?, ?, ?)
	</entry> 

Run클래스에서 값 3개를 테이블에 넣을 것이 VALUES의 ?에 들어가 DML수행 후 DB에서 INSERT를 했던 결과처럼 성공, 실패로 int를 반환한다.

0개의 댓글