필요한 사전 지식
1. 동적로딩
- Java는 동적로딩을 지원하기 때문에 실행 시에 모든 클래스가 로딩되지 않고, 필요한 시점에 클래스를 로딩할 수 있습니다. 동적로딩은 (a)로드타임 동적로딩, (b) 런타임 동적로딩이 있습니다.
(a) 로드타임 동적로딩
- 하나의 클래스를 로딩하는 과정에서 필요한 다른 클래스들을 동적으로 로딩합니다.
class Main{
public static void main(String[] args){
System.out.println("Hello World");
}
}
- Main.class가 JVM내로 로딩되면서 필요한 System, String 관련 .class들도 미리 JVM에 로딩됩니다.
- 관련 .class를 로딩하지 못한다면 Main.class를 로딩하지 못합니다.
(b) 런타임 동적로딩
- 코드를 실행하는 순간 필요한 클래스를 로딩하는 것입니다.
- JVM이 실제로 .class를 실행할 때 코드를 발견하면 관련 .class 파일을 로딩합니다.
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
}catch (ClassNotFoundException e){
//에러처리하는 코드
}
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try{
conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:xe","jsp","oracle");
stmt=conn.createStatement(); //쿼리 수행
rs=stmt.executeQuery("SELECT 1 FROM DUAL");
if(rs.next()) System.out.print(rs.getInt(1));
}catch (SQLException e){
//에러처리하는 코드
}finally {
if(rs!=null){try{rs.close();} catch(Exception e){} }
if(stmt!=null){try{stmt.close();} catch(Exception e){} }
if(conn!=null){try{conn.close();} catch(Exception e){} }
}
자바에서 DB연결까지
- JAVA에서 JDBC API를 이용해 JDBC Driver를 사용하려면 해당 드라이버가 로드되어야 합니다.
- Class.forName("oracle.jdbc.driver.OracleDriver")은 ' 이 코드를 만나면 OracleDriver 로드하고 실행해' 라는 의미가 됩니다.
- 로드만 했을 뿐 변수를 선언해 oracle 드라이브 객체를 받지도 않았는데 어떻게 바로 conn = DriverManager.getConnection()을 써서 DB에 연결할 수 있었을까요?
- 정답은 바로 Driver 클래스의 static 구문에 있습니다.
//
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
그외 기타 기능
}
static
{
defaultDriver = null;
Timestamp timestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
try
{
if(defaultDriver == null)
{
defaultDriver = new OracleDriver();
DriverManager.registerDriver(defaultDriver);
}
}
catch(RuntimeException runtimeexception) { }
catch(SQLException sqlexception) { }
}
- 로드될 때 Driver를 DriverManager라는 곳에 등록하기 때문에 바로 DB에 연결하는
Connection conn = DriverManager.getConnection("url","id","pw"); 구문을 사용해 DB에 연결할 수 있습니다.
과정 정리
- Class.forName()을 통해 실행도중 오라클 드라이브를 로드
- 로드되면서 OracleDriver에 static{} 구문을 실행하여 DriverManager에 OracleDriver를 등록
- DriverManager.getConnection()을 통해 DB에 연결
- 이후로 쿼리 진행
Class.forName()사용 이유
질문 : static{} 구문이 로딩될때 사용되는 거라면, OracleDriver driver = new OracleDriver() 로드타임 동적로딩하여 DriverManager에 등록하여 연결해도 되지 않나?
OracleDriver oracleDriver=new OracleDriver();
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try{
conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:xe","jsp","oracle");
stmt=conn.createStatement(); //쿼리 수행
rs=stmt.executeQuery("SELECT 1 FROM DUAL");
if(rs.next()) System.out.print(rs.getInt(1));
}catch (SQLException e){
//에러처리하는 코드
}finally {
if(rs!=null){try{rs.close();} catch(Exception e){} }
if(stmt!=null){try{stmt.close();} catch(Exception e){} }
if(conn!=null){try{conn.close();} catch(Exception e){} }
}
- 위의 코드에서 oracleDriver 객체는 사용되지 않습니다. 즉 쓸데없이 객체 1개를 생성하였습니다.
- Class.forName()의 매개변수에 문자열값을 직접 입력하는 것이 아니라 조건에 따라 oracle, mysql일 것입니다.
String dirverName=request.getParameter("driverName");
String connectionInfo="";
if(dirverName.equals("oracle.jdbc.driver.OracleDriver")){
connectionInfo="jdbc:oracle:thin:@127.0.0.1:1521:xe";
}else{
//오라클 말고 기타 DB Driver
}
try{
Class.forName(dirverName);
}catch (ClassNotFoundException e){
//에러처리하는 코드
}
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try{
conn=DriverManager.getConnection(connectionInfo,"jsp","oracle");
stmt=conn.createStatement(); //쿼리 수행
rs=stmt.executeQuery("SELECT 1 FROM DUAL");
if(rs.next()) System.out.print(rs.getInt(1));
}catch (SQLException e){
//에러처리하는 코드
}finally {
if(rs!=null){try{rs.close();} catch(Exception e){} }
if(stmt!=null){try{stmt.close();} catch(Exception e){} }
if(conn!=null){try{conn.close();} catch(Exception e){} }
}
- Class.forName()을 안쓰게 되면 OracleDriver를 포함한 기타 DB Driver를 전부 로드해야 합니다.
- 로드타임으로 하게 된다면 어떤 driver를 사용할지 모르므로 모든 Driver를 로드하게 됩니다.
- 하지만 Class.forName()을 사용한다면 실행도중 한가지 Driver만 로드하게 됩니다.
결론 Class.forName()을 사용하게 된다면
- Driver의 경우 로드만 하고, 객체 생성을 안해도 됩니다.
- 특정 조건에 따라 Driver 로드를 다르게 할때 쓸데없이 모든 Driver를 로드할 필요가 없습니다.
- 로드되는 시점이 컴파일이 아닌 런타임이기 때문에 static{} 구문에 실행시점을 조절할 수 있습니다.
'면접 질문지 소스' 카테고리의 다른 글
데이터베이스의 인덱스란? (0) | 2024.09.27 |
---|---|
06/12 취업특강 (0) | 2024.06.12 |
DAO, DTO, VO의 개념과 차이점 (0) | 2024.05.10 |
면접질문: Spring Framework에서 Annotation을 사용하는 예시를 설명해주세요. (0) | 2024.05.07 |
면접질문: Java Annotation에 대해 설명해주세요. (0) | 2024.05.07 |