티스토리 뷰

1.    JDBC에서 SQL 문장 2가지

-      1 ) Dynamic SQL ( 동적인 SQL )

-       : 동일한 SQL문장을 매번 생성하고 실행하는 SQL

-      2 ) Prepared SQL ( 준비된 SQL)

-       : 최초에 들어왔던 SQL문에 대한 최적화된 실행 계획을 Oracle optimizer이 저장해 두었다가, 동일한 SQL일 때 재사용함으로써 자원을 효율적으로 사용하고 SQL문을 빠르게 처리할 수 있다.

-      + Prepared SQL문을 자주 사용하며, 동적인 SQL문은 잘 사용되지 않는다.


[ 1. 준비된 SQL문 ] (****)

 

package org.zerock.myapp;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;

import lombok.extern.log4j.Log4j2;

@Log4j2
public class JDBCExample1 { // 준비된 SQL
	
//	============================================================
	// JDBC를 이용한 Target DB에 연결을 위한 정보를 아래와 같이 준비해야 한다!!
	
	// (1) JDBC URL
	// (2) Driver Class
	// (3) ID
	// (4) PassWord
//	============================================================
	// (1) JDBC URL : DB Vendor마다 조금씩 다르지만, 기본틀은 표준에 의해서 정해져있다.
	
//	final String jdbcUrl = "jdbc:<vendor명>:thin:@IP주소:포트번호/<DB이름>"; // EZCONNECT 방식
//	vendor명은 회사명을 의미하는데, Oracle인지 아니면 그외인지 회사명을 작성하는 것이다.
//	thin은 JDBC를 연결하는 방법이며, 그 아래에는 연결할 타겟의 정보를 작성하는 것이다.
	
//	final String jdbcUrl = "jdbc:oracle:thin:@<네트워크별칭(TNS Alias)?TNS_ADMIN=tnsnames.ora파일의경로>"; // TNSAlias방식
//	클라우드는 TNSAlias방식만 된다. (*****)
	
	static final String jdbcUrl = "jdbc:oracle:thin:@db00000005_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"; // (****)
	// 환경변수 TNS_ADMIN은 삭제하는 편이 좋다. ( 전자지갑의 위치가 바뀔수 있기에 )
	// TNS_ADMIN=C:/opt/OracleCloudWallet/ATP는 쿼리 스트링으로, db00000005_high의 파일(tnsnames.ora) 위치를 알려준다.(***)
	// TNS_ADMIN은 네트워크 별칭(TNS)를 관리하는 환경변수를 의미한다.
//	============================================================
	// (2) Driver Class
	
	static final String driverClass = "oracle.jdbc.OracleDriver";
//	final String driverClass = "oracle.jdbc.driver.OracleDriver"; // OK
//	============================================================
	// (3) 사용자 DB계정
	
	static final String user = "hr";
//	============================================================
	// (4) 사용자 DB 암호
	
	static final String pass = "Oracle0000000";
//	============================================================
	
	
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		
		log.info("0. user명 : " + user);
		// static은 static(정적 멤버) 내에서만 사용이 가능하다.
//		============================================================
		Connection conn = null; // 연결
		Statement stmt = null; // sql문장
		PreparedStatement pstmt = null; // 인터페이스 형태
		ResultSet rs = null; // 결과셋
		// import 잊지말고 주의해서 사용하자!!
//		============================================================
		
		// 1. JDBC Driver Class를 Method Area에 Clazz 객체로 등록
//		Class.forName("FQCN of the JDBC driver class");
		Class.forName(driverClass); // 예외처리를 해야한다.
		
//		Class.forName("a.b.c.OracleDriver"); // xx
//		============================================================
		
//		2. driverClass를 이용해서 연결시도 ( To connect to the specified Oracle Instance using driverClass )
		conn = DriverManager.getConnection(jdbcUrl, user, pass); // 예외처리를 해야한다.
//		Connection java.sql.DriverManager.getConnection(String url, String user, String password) throws SQLException
		
		log.info("2. conn : "+ conn);
//		============================================================
		
//		3. To create a Statement object from Connection object ( Connection 객체로부터 정적 객체 생성하기 )
//		conn.createStatement(); // 동적인 SQL문을 작성할 때 ( 동일한 SQL문장을 매번 생성 및 실행 )
//		conn.prepareStatement(); // 준비된 SQL문을 작성할 때 ( 동일한 SQL문일 경우, 최적화 실행계획 재사용 ) (****)
		
		String sql = "SELECT * FROM employees WHERE salary >= ?"; // ?는 Bind Variable이라고 한다.
		
		pstmt = conn.prepareStatement(sql);
		// PreparedStatement java.sql.Connection.prepareStatement(String sql) throws SQLException
		// String 타입으로 sql문을 작성해 줘야 한다.
		
		pstmt.setDouble(1, 10000); // (****)
		// 이를 통해서 ?(Bind Variable)에 값을 지정해 줄 수 있다.
		// 1은 몇번째 Bind Variable인지 지정하는 것으로, Bind Variable은 1번부터 시작한다.
		// 10000는 Bind Variable에 들어갈 값을 지정한 것이다.
		// Bind Variable은 준비된 SQL에서만 가능하기에, 동적에서는 불가능 하다.
		
		log.info( "3. pstmt : " + pstmt );
//		============================================================
		
//		4. SQL문 실행하기 ( To execute the specified Statement, SQL )
		rs = pstmt.executeQuery();  // DQL
//		int affectedLines = pstmt.executeUpdate(); // DML
//		executeUpdate()는 sql문으로 영향을 받은 라인의 개수를 반환해 준다.
		
		log.info("4. rs : " + rs);
//		============================================================
		
//		5. TO get All records from ResultSet object (***)
		while( rs.next() ) {
			
			// 가져올 속성을 기제해야 한다.
			int employeeId = rs.getInt("EMPLOYEE_ID");
			String firstName = rs.getString("FIRST_NAME");
			String lastName = rs.getString("LAST_NAME");
			String email = rs.getString("EMAIL");
			String phone = rs.getString("PHONE_NUMBER");
			Date hireDate = rs.getDate("HIRE_DATE");
			String jodId = rs.getString("JOB_ID");
			double salary = rs.getDouble("SALARY");
			double commPct = rs.getDouble("COMMISSION_PCT");
			int managerId = rs.getInt("MANAGER_ID");
			int departmentId = rs.getInt("DEPARTMENT_ID");
			
			String employee = 
					String.format(
							"%s %s %s %s %s %s %s %s %s %s %s", 
							employeeId, firstName, lastName, email, phone, hireDate, jodId, salary, commPct, managerId, departmentId );
			
			log.info( "+ employee : " + employee);
			
		} // while - 다음 레코드가 남아있으면 무한 반복 		
//		============================================================
		
//		5. To close current Connection ( 연결 끊기 - 순서중요!!! )

		assert rs != null; // = if(rs != null ) // = Objects.requireNonNull(rs); (**)
		rs.close(); // 자원해제
		
		assert pstmt != null;
		pstmt.close(); // 자원해제를 해야한다.
		
		assert conn != null;
		conn.close();
		log.info("Connection Closed");
		
		// + 반드시 자원을 해제해 줘야지 운영체제가 망가지지 않는다. (***)
//		============================================================
		
	} // end main

} // end class

[ 2. 동적인 SQL ]

 

package org.zerock.myapp;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;

import lombok.extern.log4j.Log4j2;

@Log4j2
public class JDBCExample2 { // 동적 SQL
	
	static final String jdbcUrl = "jdbc:oracle:thin:@db00000000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"; // (****)
	static final String driverClass = "oracle.jdbc.OracleDriver";
	static final String user = "hr";
	static final String pass = "Oracle00000";
	
	public static void main(String[] args) throws ClassNotFoundException, SQLException {

		Connection conn = null; // 연결
		Statement stmt = null; // sql문장
		PreparedStatement pstmt = null; // 인터페이스 형태
		ResultSet rs = null; // 결과셋
		
//		1. JDBC Driver Class를 Method Area에 Clazz 객체로 등록
		Class.forName(driverClass); // 예외처리를 해야한다.
		
//		2. driverClass를 이용해서 연결시도 ( To connect to the specified Oracle Instance using driverClass )
		conn = DriverManager.getConnection(jdbcUrl, user, pass); // 예외처리를 해야한다.
		log.info("2. conn : "+ conn);
		
//		3. To create a Statement object from Connection object ( Connection 객체로부터 정적 객체 생성하기 )
		String sql = "SELECT * FROM employees";
		stmt = conn.createStatement(); // 동적인 SQL문을 작성할 때 ( 동일한 SQL문장을 매번 생성 및 실행 )
		log.info("3. stmt : " + stmt);
		
//		4. SQL문 실행하기 ( To execute the specified Statement, SQL )
		rs = stmt.executeQuery(sql);  // DQL
		log.info("4. rs : " + rs);
		
//		5. TO get All records from ResultSet object (***)
		while( rs.next() ) {
			
			// 가져올 속성을 기제해야 한다.
			int employeeId = rs.getInt("EMPLOYEE_ID");
			String firstName = rs.getString("FIRST_NAME");
			String lastName = rs.getString("LAST_NAME");
			String email = rs.getString("EMAIL");
			String phone = rs.getString("PHONE_NUMBER");
			Date hireDate = rs.getDate("HIRE_DATE");
			String jodId = rs.getString("JOB_ID");
			double salary = rs.getDouble("SALARY");
			double commPct = rs.getDouble("COMMISSION_PCT");
			int managerId = rs.getInt("MANAGER_ID");
			int departmentId = rs.getInt("DEPARTMENT_ID");
			
			String employee = 
					String.format(
							"%s %s %s %s %s %s %s %s %s %s %s", 
							employeeId, firstName, lastName, email, phone, hireDate, jodId, salary, commPct, managerId, departmentId );
			
			log.info( "+ employee : " + employee);
			
		} // while - 다음 레코드가 남아있으면 무한 반복 		
		
//		5. To close current Connection ( 연결 끊기 - 순서중요!!! )

		assert rs != null; // = if(rs != null ) // = Objects.requireNonNull(rs); (**)
		rs.close(); // 자원해제
		
		assert stmt != null;
		stmt.close(); // 자원해제를 해야한다.
		
		assert conn != null;
		conn.close();
		log.info("Connection Closed");
		
	} // end main

} // end class

[ 3. Driver Class 객체 생략 버전 ] (***) 

 

package org.zerock.myapp;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.Objects;

import lombok.extern.log4j.Log4j2;

@Log4j2
public class JDBCExample3 {
	
	static final String jdbcUrl = "jdbc:oracle:thin:@db0000000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"; // (****)
//	static final String driverClass = "oracle.jdbc.OracleDriver";
	static final String user = "hr";
	static final String pass = "Oracle000";
	
	public static void main (String [] args) throws SQLException {
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		// 1 단계 생략 버전! ( Driver Class 객체 생략 ) - Driver Class는 이제 등록하지 않아도 된다.
		
		// 2. 연결 얻어내기
		conn = DriverManager.getConnection(jdbcUrl, user, pass);
		
		// 3. To Create a PreparedStatement sql
		String sql = "SELECT employee_id, last_name, hire_date, salary, department_id "
				+ "FROM employees "
				+ "WHERE salary > ? "
				+ "ORDER BY salary DESC";
		pstmt = conn.prepareStatement(sql);
		pstmt.setDouble(1, 5000); // ?값 설정
		
		// 4. Execution ( 실행 )
		rs = pstmt.executeQuery();
		
		// 5. 데이터 추출
		while( rs.next() ) {
			
			int employeeId = rs.getInt("EMPLOYEE_ID");
			String lastName = rs.getString("last_name");
			Date hireDate = rs.getDate("HIRE_DATE");
			double salary = rs.getDouble("SALARY");
			int departmentId = rs.getInt("DEPARTMENT_ID");
			// 칼럼명은 대소문자 구분하지 않는다.
			
			log.info("\t + employee : {} {} {} {} {}", employeeId, lastName, hireDate, salary, departmentId); // (****)
			
		} // while
		
		// 6. 자원해제
		Objects.requireNonNull(rs);
		rs.close();
		
		if(pstmt != null ) pstmt.close();
		
		assert conn != null;
		conn.close();
		
	} // end main

} // end class

[ 4. try - with - resource로 자원 해제 - java7까지 ]

 

package org.zerock.myapp;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;

import lombok.extern.log4j.Log4j2;

@Log4j2
public class JDBCExample4 { // try - with - resource 1 - until java7s

	static final String jdbcUrl = "jdbc:oracle:thin:@db00000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"; // (****)
	static final String user = "hr";
	static final String pass = "Oracle000";
	
	public static void main(String[] args) throws SQLException {
		
//		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try ( Connection conn = DriverManager.getConnection(jdbcUrl, user, pass); ) { // until java7
			
			String sql = new StringBuffer().
					append("SELECT employee_id, last_name, hire_date, salary, department_id ").
					append("FROM employees ").
					append("WHERE salary > ? ").
					append("ORDER BY salary DESC").toString(); // (****)
			// StringBuffer은 문자열을 다닥다닥 붙이기 때문에 공백을 직접 입력해줘야 한다.
			// 자원 효율성을 위해서 StringBuffer이나 StringBuilder를 필수로 사용해야 한다. (****)
			
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, "7000");
			
			rs = pstmt.executeQuery(); // 실행
			
			while( rs.next() ) {
				String employeeId = rs.getString("EMPLOYEE_ID");
				String lastName = rs.getString("last_name");
				String hireDate = rs.getString("HIRE_DATE");
				String salary = rs.getString("SALARY");
				String departmentId = rs.getString("DEPARTMENT_ID");
				// 칼럼명은 대소문자 구분하지 않는다.
				
				log.info("\t + employee : {} {} {} {} {}", employeeId, lastName, hireDate, salary, departmentId); // (****)
			} // while
			
			// 자원해제
			Objects.requireNonNull(rs);
			rs.close();
			
			if(pstmt != null ) pstmt.close();
			// + conn 자원 해제는 try - with - resource로 한다.
			// conn은 Connection 인터페이스가 AutoCloseable하고 있기에 가능한 것이다. (***)
			// AutoCloseable이 없으면 try - with - resource으로는 자원해제가 불가능하다.
			
		} // try - with - resource
		
	} // end main
	
} // end class

[ 5. try - with - resource로 자원 해제 - java8 이상 ] (****)

 

package org.zerock.myapp;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import lombok.extern.log4j.Log4j2;

@Log4j2
public class JDBCExample5 {
	
	static final String jdbcUrl = "jdbc:oracle:thin:@db00000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"; // (****)
	static final String user = "hr";
	static final String pass = "Oracle000";
	
	public static void main(String[] args) throws SQLException {
		
		Connection conn = DriverManager.getConnection(jdbcUrl, user, pass);
		
		String sql = new StringBuffer().
				append("SELECT employee_id, last_name, hire_date, salary, department_id ").
				append("FROM employees ").
				append("WHERE salary > ? ").
				append("ORDER BY salary DESC").toString(); // (****)
		
		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, "7000");
		
		ResultSet rs = pstmt.executeQuery(); // 실행
		
		try ( conn; pstmt; rs; ) { // over java8	
			
			while( rs.next() ) {
				String employeeId = rs.getString("EMPLOYEE_ID");
				String lastName = rs.getString("last_name");
				String hireDate = rs.getString("HIRE_DATE");
				String salary = rs.getString("SALARY");
				String departmentId = rs.getString("DEPARTMENT_ID");
				// 칼럼명은 대소문자 구분하지 않는다.
				
				log.info("\t + employee : {} {} {} {} {}", employeeId, lastName, hireDate, salary, departmentId); // (****)
			} // while
			
			// 자원 해제를 try - with - resource에서 해주었다.
			// 단, try - with - resource에서 자원해제하기 위해서는 AutoCloseable해야 한다.
			// try( )에서 자원해제는 오른쪽에서 왼쪽으로 순서대로 진행된다.
			
		} // try - with - resource
		
	} // end main

} // end class

[ 6. try - with - resource로 자원 해제 2 - java8 이상 ]

 

package org.zerock.myapp;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import lombok.extern.log4j.Log4j2;

@Log4j2
public class JDBCExample5 {
	
	static final String jdbcUrl = "jdbc:oracle:thin:@db000000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"; // (****)
	static final String user = "hr";
	static final String pass = "Oracle000";
	
	public static void main(String[] args) throws SQLException {
		
		Connection conn = DriverManager.getConnection(jdbcUrl, user, pass);
		
		String sql = new StringBuffer().
				append("SELECT employee_id, last_name, hire_date, salary, department_id ").
				append("FROM employees ").
				append("WHERE salary > ? ").
				append("ORDER BY salary DESC").toString(); // (****)
		
		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, "7000");
		
		try ( conn; pstmt; ) { // over java8	
			
			// rs의 경우 DB의 데이터를 활용할 지점이 오면 rs를 사용한다. 그렇기에 이렇게 작성할 수도 있다.
			
			ResultSet rs = pstmt.executeQuery(); // 실행
			
			try ( rs; ) {
				
				while( rs.next() ) {
					
					String employeeId = rs.getString("EMPLOYEE_ID");
					String lastName = rs.getString("last_name");
					String hireDate = rs.getString("HIRE_DATE");
					String salary = rs.getString("SALARY");
					String departmentId = rs.getString("DEPARTMENT_ID");
					// 칼럼명은 대소문자 구분하지 않는다.
					
					log.info("\t + employee : {} {} {} {} {}", employeeId, lastName, hireDate, salary, departmentId); // (****)
					
				} // while
				
			} catch(Exception e) {
				e.printStackTrace();
			} // inner - try- catch
			
			// 자원 해제를 try - with - resource에서 해주었다.
			// 단, try - with - resource에서 자원해제하기 위해서는 AutoCloseable해야 한다.
			// try( )에서 자원해제는 오른쪽에서 왼쪽으로 순서대로 진행된다.
			
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} // try - with - resource
		
	} // end main

} // end class

[ 7. 자료구조를 생성하여 데이터 활용 - @Value ] (*****)

 

[ 7 - 1. 자료구조 생성 ]

package org.zerock.myapp.domain;

import lombok.Value;

// @Value는 Read-only이기에 getter은 제공해도 setter는 없다.
// @Value = VO(Value Object) : Read only object (**)
// DB 테이블의 1개의 레코드를 저장할 수 있는 객체를 생성하는 클래스에 적합하다.(***)

// setter까지 하려면 @Data를 사용하는 것이 좋다. (**)
// @Data = DTO(Data Transfer object) : 프런트에서 얻은 데이터를 백엔드로 넘겨줄때 사용(***)

@Value
public class Employee {
	
	private String employeeId; 
	private String lastName;
	private String hireDate;
	private String salary; 
	private String departmentId;

} // end class

 

[ 7 - 2. 자료구조 활용 ]

 

package org.zerock.myapp;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.zerock.myapp.domain.Employee;

import lombok.extern.log4j.Log4j2;

@Log4j2
public class JDBCExample6 {
	
	static final String jdbcUrl = "jdbc:oracle:thin:@db000000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP";
	static final String user = "hr";
	static final String pass = "Oracle000";
	
	public static void main(String[] args) {
		
		try {
			
			Connection conn = DriverManager.getConnection(jdbcUrl, user, pass);
			
			String sql = new StringBuffer().
					append("SELECT employee_id, last_name, hire_date, salary, department_id ").
					append("FROM employees ").
					append("WHERE salary > ? ").
					append("ORDER BY salary DESC").toString(); // (****)
			
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, "7000");
			
			ResultSet rs = pstmt.executeQuery(); // 실행
			// rs는 rs.getString할때, 비로소 활동하기 때문에 조심해야 한다.
			
			List<Employee> employees = new ArrayList<>();
			
			try ( conn; pstmt; rs; ){
				// 오른쪽에서 왼쪽순으로 닫아준다.
				
				while ( rs.next() ) {
					
					String employeeId = rs.getString("EMPLOYEE_ID");
					String lastName = rs.getString("last_name");
					String hireDate = rs.getString("HIRE_DATE");
					String salary = rs.getString("SALARY");
					String departmentId = rs.getString("DEPARTMENT_ID");
					// 칼럼명은 대소문자 구분하지 않는다.

					// 적절한 자료구조를 만들어 저장 - VO(Value Object)
					Employee emp = new Employee( employeeId, lastName, hireDate, salary, departmentId );
					
					employees.add(emp); // ArrayList에 원소 추가하기
					
				} // while
				
			} //try -with - resources ( try()안에 지정되어 있는 자원을 블록이 끝나면 자동으로 해제시켜준다. )
			
			//=================================
			// 일련의 비지니스 로직 수행 자리 ( 자료구조에 저장된 DB데이터 사용 )
			// 위에서 생성한 자료구조 이용
			
//			for ( Employee em : employees ) {
//				log.info( "\t + employee : " + em);
//			} // enhanced for
			
			employees.forEach( e -> log.info(e) ); // forEach(*****)
			
			//=================================
			
			// 자원은 빨리 끊어줄 수록 좋다.
			// 그렇기 때문에 ResultSet은 빨리 얻어내는 것이 좋다. (**)
			// + 즉, ReultSet 얻기 -> 비지니스 로직 수행
			
			employees.clear();
			// ArrayList는 AutoCloseable하지 않기에, 비지니스 로직 후에 해제시켜줘야 한다.
			
		} catch(SQLException e) {
			e.printStackTrace();
		} // try - catch ( try블록 내에서 발생한 예외를 catch에 지정해 주어 예외를 추적하게 한다. )
		
	} // main

} //end class

[ 8. 준비된 SQL문 - affectedLines 수 구하기 ( .executeUpdate( ) ) ] (*)

 

package org.zerock.myapp;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

import lombok.extern.log4j.Log4j2;

@Log4j2
public class JDBCExample7 {
	
	static final String jdbcUrl = "jdbc:oracle:thin:@db0000000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP";
	static final String user = "hr";
	static final String pass = "Oracle000";
	
	public static void main(String[] args) {
		
		String sql = "INSERT INTO departments(department_id, DEPARTMENT_NAME) VALUES(?, ?)";
		// 추가하는 sql문 
		// sql문은 ;을 포함해서는 안된다.
		
		try {
			
			Connection conn = DriverManager.getConnection(jdbcUrl, user, pass); // Connection 객체는 기본적으로 Auto Commit을 해준다.
			// conn.setAutoCommit(false);로 자동 커밋을 해제시켜줄 수도 있다.
			
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, 500);
			pstmt.setString(2, "영화 500");
			
			int affectedLines = 0;
			
			try ( conn; pstmt; ){
				affectedLines = pstmt.executeUpdate(); // 영향을 받은 라인의 수를 알려준다.
				log.info("+ affectedLines : {}", affectedLines);
				// 하나만 생성되었기 때문에 affectedLines 값이 1로 나온다.
			} // try - with - resources
			
			// 비지니스 로직 수행
			
		} catch (Exception e) {
			e.printStackTrace();
		} // try - catch
		
	} // end main

} // end class

[ 9. try - with - resources에서 자원이 닫히는 순서 ]

 

package org.zerock.myapp;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;

@Log4j2
public class JDBCExample8 {
	
	public static void main(String[] args) {
		
		MyResource res1 = new MyResource(); res1.setName("MyResource1");
		MyResource res2 = new MyResource(); res2.setName("MyResource2");
		MyResource res3 = new MyResource(); res3.setName("MyResource3");
		
		log.info("res1 : {}, res2 : {}, res3 : {}", res1.getName(), res2.getName(), res3.getName());
		
		try( res1; res2; res3; ){
			;;
		} catch(Exception e) {
			e.printStackTrace();
		} // try - with - resources
		
//		14:50:04.828 TRACE --- [      main] o.z.m.MyResource.close:40 - Resource : MyResource3 closed
//		14:50:04.829 TRACE --- [      main] o.z.m.MyResource.close:40 - Resource : MyResource2 closed
//		14:50:04.829 TRACE --- [      main] o.z.m.MyResource.close:40 - Resource : MyResource1 closed
		// try()에서는 오른쪽에서 왼쪽순으로 자원이 닫히고 있음을 알 수 있다.
		
	} // end class

} //end class


@Log4j2
@NoArgsConstructor
class MyResource implements AutoCloseable {
	
	@Getter
	@Setter
	private String name;
	
	@Override
	public void close() throws Exception {
		log.trace("Resource : {} closed", this.name);
	} // end close()
	
} // end MyResource
728x90

'KH 정보교육원 [ Java ]' 카테고리의 다른 글

KH 83일차 - Driver SPY / junit  (0) 2022.06.27
KH 82일차 - WAS  (0) 2022.06.24
KH 80일차 - JDBC 1 ( Target DB에 연결 )  (0) 2022.06.22
KH 79일차 - 메이븐 2  (0) 2022.06.21
KH 78일차 - 메이븐  (0) 2022.06.21
댓글
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
최근에 올라온 글
Total
Today
Yesterday
공지사항