사용자 도구

사이트 도구


java:jdbc

JDBC

Timeout

  • DB 연결 설정에서 Timeout은 매우 중요한 부분임. 모두 설정하고 의미 숙지
  • connection timeout
  • socket timeout
  • statement timeout(query timeout)
  • 각 Connection Pool에서 커넥션을 가져오는 최대 대기시간 설정도 꼭 해준다. connection timeout보다 약간 더 길게 하면 될까?

편리 라이브러리

SQL Logging

Db 접속 테스트. 가장 기본 JDBC 접속 및 쿼리

public class DbTester {
    public static void main(String[] args) throws Exception {
        if (args.length != 4) {
            System.err.println("Usage: java -cp [dbjdbcdriver.jar]:. DbTester [jdbcurl] [db-username] [db-password] [sql]");
        }
        String jdbcUrl = args[0];
        String username = args[1];
        String password = args[2];
        String sql = args[3];
 
        testDb(jdbcUrl, username, password, sql);
    }
 
    public static void testDb(String jdbcUrl, String username, String password, String sql) throws SQLException {
        Connection con = null;
        Statement statement = null;
        try {
            System.out.println(">> Processing JDBC URL : "+ jdbcUrl);
            Class.forName(“driverClassFQCN”); // no need in Java 6/JDBC 4
            con = DriverManager.getConnection(jdbcUrl, username, password);
            statement = con.createStatement();
            boolean executed = statement.execute(sql);
            System.out.println(String.format("Executed '%s' result - %s", sql, executed));
        } finally {
            if (statement != null) {
                con.close(); // 사실은 try/catch로 묶어야함.
            }
            if (con != null) {
                con.close(); // 여기도 try/catch로 묶어야함.
            }
        }
    }
}

JDBC Driver

  • DriverManager.getDriver(jdbcUrl)은 각 JDBC Driver 객체의 Driver.acceptsURL(url)을 호출하여 해당 JDBC URL을 처리할 수 있는 Driver를 골라 커넥션을 맺도록 한다.
    • 이 때문에 동일 JDBC URL을 사용하는 두 개 이상의 JDBC 드라이버를 등록할 수 없다.
    • 해결책은 조금 변현된 URL을 받아들이도록 처리한 새로운 Driver를 만들고 이를 기존 드라이버에 위임하면 된다.(acceptsURL Override 필요).
  • 새로운 드라이버 클래스를 만들 때 주의할 점.

HA-JDBC

  • HA-JDBC 어느 JDBC 드라이버에서나 사용할 수 있는 클러스터링 DB JDBC Driver

Connection.setClientInfo

  • JDBC 4(Java 6 이후)를 지원하는 JDBC 드라이버의 경우 지원한다.
  • Connection.setClientInfo()를 통해 값을 설정하면 JDBC 드라이버가 이를 자기만의 방법으로 DB 서버로 전송한다.
  • MySQL JDBC의 경우 기본적으로는 주석(Comment)로 달아주는 등의 역할을 한다.
  • BoneCP의 경우 BoneCPDataSource.setClientInfo(properties)로 설정하면 자동으로 Connection.setClientInfo를 매번 호출하여 지정된 모든 프라퍼티를 세팅해준다.
  • 기본 프라퍼티
  • ApplicationName - The name of the application currently utilizing the connection
  • ClientUser - The name of the user that the application using the connection is performing work for. This may not be the same as the user name that was used in establishing the connection.
  • ClientHostname - The hostname of the computer the application using the connection is running on.
  • 예제 코드 :
    BoneCPDataSource dataSource = new BoneCPDataSource();
    dataSource.setDriverClass(com.mysql.jdbc.Driver.class.getCanonicalName());
    dataSource.setUser("root");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF8");
    dataSource.setLogStatementsEnabled(true);
    Properties clientInfo = new Properties();
     
    clientInfo.setProperty("ApplicationName", "This is JDBC TEST");
    InetAddress addr = InetAddress.getLocalHost();
     
    clientInfo.setProperty("ClientHostname", addr.getHostName());
    clientInfo.setProperty("ClientHostaddress", addr.getHostAddress());
     
    dataSource.setClientInfo(clientInfo);
     
     
    Connection connection = dataSource.getConnection();
     
    Statement statement = connection.createStatement();
    statement.executeQuery("select * from xxx /* hello world! */");
    statement.close();
    dataSource.close();
  • 서버의 Query Log에 남은 결과 :
    /* ApplicationName=This is JDBC TEST, ClientHostname=kwon37xi-dev, ClientHostaddress=127.0.1.1 */ 
    select * from xxx 
    /* hello world! */

JDBC 4 DriverManager

  • JDBC 4의 DriverManager는 기존처럼 Class.forName(“driverClassFQCN”) 처리 과정이 없어도 자동으로 JDBC Driver를 등록해주는 기능이 있다.
  • JDBC Driver가 JDBC 4를 구현하고 jar 파일 안에 META-INF/services/java.sql.Driver파일이 존재하고 그 안에 Driver Class FQCN이 기입돼 있어야 한다.
  • 이는 DriverManager와 각 JDBC Driver 클래스들의 Class Loader가 일치할 때만 작동하는 것 같다.
    When the method getConnection is called, the DriverManager will attempt to locate a suitable driver
    from amongst those loaded at initialization and those loaded explicitly using the same classloader
    as the current applet or application. 
  • 따라서 Tomcat에 웹 애플리케이션으로 올리거나 할 때는 WEB-INF/lib에 JDBC 드라이버가 있으면 JDBC 드라이버 자동로딩 기능은 작동하지 않는 것으로 보인다.
  • ${CATALINA_HOME}/lib에 두어야 올바로 작동하는 듯 하다.

특정 Table 의 meta data 얻기

try (Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3307/dbname", "username", "password")) {
    final DatabaseMetaData metaData = con.getMetaData();
 
    final ResultSet rs = metaData.getTables(null, null, "[tableName]", new String[] { "TABLE" });
 
    while(rs.next()) {
        final ResultSetMetaData rsMetaData = rs.getMetaData();
        final int columnCount = rsMetaData.getColumnCount();
        for (int i = 1; i <= columnCount; i++) {
            System.out.println("column " + i + ", column name: " + rsMetaData.getColumnName(i) + " , value: " + rs.getString(i)));
        }
    }
}

SQL 생성

참고

java/jdbc.txt · 마지막으로 수정됨: 2019/06/25 16:13 저자 kwon37xi