티스토리 뷰
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 |
댓글