'jdbc'에 해당되는 글 15

  1. 2010.07.09 JDBC 드라이버에서 날리는 쿼리 확인 - SQL Server
  2. 2010.05.14 JDBC URL for Oracle RAC 1
  3. 2009.12.05 JDBC로 프로시저 호출하기
  4. 2009.08.14 시스템 Hangup 현상 분석
  5. 2009.07.25 SQL Server 2005에서 SchemaSpy 실행하기
  6. 2009.07.24 Apache Derby
  7. 2009.06.18 Oracle JDBC Driver, 버전 및 크기
  8. 2009.05.11 Microsoft SQL Server JDBC Driver
  9. 2009.05.11 MySQL JDBC Driver
  10. 2009.05.05 JDBC Code Template - 프로시저
  11. 2009.04.29 JDBC Code Template
  12. 2009.04.23 해서는 안되는 예외 처리 - 아무것도 안하는 경우
  13. 2009.04.18 좋은 코딩 습관 - 리턴값 확인
  14. 2009.04.15 데이터 확인용 JSP/미완/spring/jndi추가
  15. 2008.12.26 시스템 정보 조회용 JSP

JDBC 드라이버에서 날리는 쿼리 확인 - SQL Server

JDBC 프로그램에서 쿼리를 날렸을 때 DBCC INPUTBUFFER spid 의 결과

- Profiler를 이용하면 쿼리와 매개변수까지 확인 가능함.

- sqljdbc.jar - 569KB (583,286 바이트) 사용, SQL Server 2005

DriverManager.getConnection()
Language Event    0     set transaction isolation level  read committed  set implicit_transactions off

Connection#setAutoCommit(false)
Language Event    0    set implicit_transactions on

Statement#executeQuery()
Language Event    0    SELECT top 2 * FROM TB_SAMPLE

PreparedStatement#executeQuery()
Language Event    0     set transaction isolation level  read committed  set implicit_transactions off //실행시킨 쿼리문을 확인할 수 없음, getConnection() 호출시 남아 있던 문장

CallableStatement#executeQuery()
//상동

SYSPROCESSES에서 program_name을 확인할 수 없음.

- jtds-1.2.2 사용, SQL Server 2005
DriverManager.getConnection()
Language Event    0    SELECT @@MAX_PRECISION  SET TRANSACTION ISOLATION LEVEL READ COMMITTED  SET IMPLICIT_TRANSACTIONS OFF  SET QUOTED_IDENTIFIER ON  SET TEXTSIZE 2147483647

Connection#setAutoCommit(false)
Language Event    0    SET IMPLICIT_TRANSACTIONS ON

Statement#executeQuery()
Language Event    0    SELECT top 2 * FROM TB_SAMPLE

PreparedStatement#executeQuery()
Language Event    0    (@P0 nvarchar(4000))SELECT top 2 * FROM TB_SAMPLE WHERE key =  @P0

CallableStatement#executeQuery()
RPC Event    0    DB123.dbo.pr_test;1

SYSPROCESSES에서 program_name이 jTDS로 확인됨.

- 연결된 서버를 통한 4파트 쿼리나 Openquery도 위와 동일함.
모두 Language Event 이다.

- auto commit이 false면 opentran 1, 그러나 락은 안보임

- sqljdbc.jar - 569KB (583,286 바이트) 사용, SQL Server 2000
커넥션 붙는 부분 위와 동일

CallableStatement, PreparedStatement#executeQuery()
RPC Event    0    sp_prepexec;1

- jtds-1.2.2 사용, SQL Server 2000
CallableStatement#executeQuery()
RPC Event    0    PR_test;1

PreparedStatement#executeQuery()
RPC Event    0    sp_execute;1

- 2005에서 실행된 쿼리를 볼 때 이 쿼리를 이용한다.

- 연결된 서버
처음 접속한 서버(2005)는 일반적인 커넥션과 동일하고, 연결된 원격의 서버(2000)에서 확인해보면 다음과 같은 특징을 가진다.

sp_who
spid ecid status      loginame    hostname        blk  dbname
58    0     dormant    test_user    DBS2005          0     NULL

sysprocesses에서 hostname이 DBS2005 이고 program_name이 Microsoft SQL Server 이다.

dbcc inputbuffer (58)
RPC Event    0    sp_reset_connection;1

JDBC URL for Oracle RAC

Connection refused(DESCRIPTION=(TMP=)(VSNNUM=186646784)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))

jdbc:oracle:thin:@1.2.3.4:1521:SID //일반적인 방법, RAC으로 구성된 경우 위와 같은 에러 발생함.

jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=
    (ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4)(PORT=1521))
    (ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5)(PORT=1521))
    (FAILOVER=on)(LOAD_BALANCE=on)
)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ZCGS))) //WebLogic 설정인데 오류가 발생함. failover가 description밖으로 나와야 할거 같다.

jdbc:oracle:thin:@(DESCRIPTION=(FAIL_OVER=ON)(LOAD_BALANCE=ON)(ADDRESS_LIST=
    (ADDRESS = (PROTOCOL = TCP) (HOST = 1.2.3.4) (PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP) (HOST = 1.2.3.5) (PORT = 1521))
)(CONNECT_DATA =(SERVICE_NAME = ZCGS)
    (FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRY=180)(DELAY=5)))
) //검색해서 가져온 설정, 된다.

jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)
    (ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))
    (ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=service))) //이것도 된다고 함. 이게 더 나을거 같다.

jdbc:oracle:thin:@1.2.3.4^1.2.3.5:1521:SID //이건 안됨.

- http://www.jugpadova.it/articles/2007/04/11/jdbc-url-for-oracle-rac

JDBC로 프로시저 호출하기

- SQL Server에서 SELECT 결과를 리턴하는 경우
getDatabaseProductName : Microsoft SQL Server
getDatabaseProductVersion : 9.00.1399
getDriverName : Microsoft SQL Server 2005 JDBC Driver
getDriverVersion : 1.2.2828.100
getDriverVersion(int) : 1.2
getJDBCVersion : 3.0

- 위와 동일한 환경에서 PreparedStatement로 프로시저 실행

[todo] openquery로도 가능하지 않나?

시스템 Hangup 현상 분석

Z건설사 시스템이 페이지가 열리지 않는 경우가 발생함.

[todo] 스레드덤프를 남겼지만 분석을 하지 못함.

어디에서 발생하는 에러인지 원인이 WAS인지 DB인지 파악도 안됨.

DBCP 설정에서 removeAbandoned, logAbandoned를 true로 두고 모니터링을 함.

예외처리도 정확하게 되었지만 Connection이 닫히지 않아 누수가 되고 있다.

[todo] 스레드덤프받아서 분석해보자.

SQL Server 2005에서 SchemaSpy 실행하기

- 데이터베이스 타입을 mssql05로 두고, 드라이버를 sqljdbc.jar를 사용한 경우 아래와 같은 에러가 발생한다.

Failed to retrieve column comments: com.microsoft.sqlserver.jdbc.SQLServerException: variant 데이터 형식은 지원되지 않습니다.
SELECT OBJECT_NAME(c.object_id) AS TABLE_NAME, c.name AS COLUMN_NAME, ex.value AS comments FROM sys.columns c LEFT OUTER JOIN sys.extended_properties ex ON ex.major_id = c.object_id AND ex.minor_id = c.column_id AND ex.name = 'MS_Description' WHERE OBJECTPROPERTY(c.object_id, 'IsMsShipped')=0 ORDER BY OBJECT_NAME(c.object_id), c.column_id
com.microsoft.sqlserver.jdbc.SQLServerException: 연결이 닫혔습니다.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerDatabaseMetaData.checkClosed(Unknown Source)
    ...
    at net.sourceforge.schemaspy.SchemaAnalyzer.analyze(SchemaAnalyzer.java:164)
    at net.sourceforge.schemaspy.Main.main(Main.java:21)

- 데이터베이스 타입을 mssql05-jtds로 바꾼다.

Apache Derby

- http://db.apache.org/derby/

- 더비는 임베디드되거나 서버 형태로 구동될 수 있다.

- Embedded Derby
  • jdbc:derby:testDerbyDB;create=true
  • create=true 옵션은 데이터베이스가 없는 경우 생성하도록 한다.
  • 데이터베이스명만 있는 경우 사용자 디렉토리에 데이터베이스가 생긴다.(이 경우 C:\Documents and Settings\USER\testDerbyDB)
  • /testDerbyDB 이면 C드라이브에 생성됨, 절대경로로 지정할 수도 있음.
  • org.apache.derby.jdbc.EmbeddedDriver
  • derby.jar: contains the Derby engine and the Derby Embedded JDBC driver

- Derby Network Server
  • jdbc:derby://localhost:1527/testDerbyDB;create=true
  • DERBY/bin/startNetworkServer 로 서버를 시작할 수 있다.
  • 데이터베이스는 서버를 실행시킨 디렉토리에 생성된다. Eclipse에서 Ant로 실행시키면 프로젝트 루트에 생긴다.
  • org.apache.derby.jdbc.ClientDriver
  • 클라이언트 : derbyclient.jar
  • 서버 : derbyrun.jar, derbynet.jar, derby.jar

- 참고
Apache Derby로 개발하기 -- Trifecta: Apache Derby 소개 (한글)
Derby 소개
Cloudscape FAQ (한글)
derby의 유용한 기능

Oracle JDBC Driver, 버전 및 크기

ssss

- http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html
  • Oracle Database 11g Release 1 (11.1.0.7.0) JDBC Drivers
    ojdbc5.jar (1,890,499 bytes) - Classes for use with JDK 1.5.
    ojdbc6.jar (1,988,051 bytes) - Classes for use with JDK 1.6.
  • Oracle Database 11g Release 1 (11.1.0.6.0) JDBC Drivers
    ojdbc5.jar (1,879,860 bytes)
    ojdbc6.jar (1,977,267 bytes)
  • Oracle Database 10g Release 2 (10.2.0.4) JDBC Drivers
    classes12.jar (1,609,607 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,555,682 bytes) - classes for use with JDK 1.4 and 1.5
  • Oracle Database 10g Release 2 (10.2.0.3) JDBC Drivers
    classes12.jar (1,600,090 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,545,954 bytes) - classes for use with JDK 1.4 and 1.5
  • Oracle Database 10g Release 2 (10.2.0.2) JDBC Drivers
    classes12.jar (1,594,191 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,540,457 bytes) - classes for use with JDK 1.4 and 1.5
  • Oracle Database 10g Release 2 (10.2.0.1.0) JDBC Drivers
    classes12.jar (1,590,491 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,536,979 bytes) - classes for use with JDK 1.4 and 1.5
  • Oracle Database 10g 10.1.0.5 JDBC Drivers
    classes12.jar (1,442,469 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,378,346 bytes) - classes for use with JDK 1.4
  • Oracle Database 10g 10.1.0.2 JDBC Drivers
    classes12.jar (1,417,089 bytes) - for use with JDK 1.2 and JDK 1.3
    ojdbc14.jar (1,352,918 bytes) - classes for use with JDK 1.4
  • Oracle9i 9.2.0.8 JDBC Drivers
    ojdbc14.jar - JDBC classes (1,212,964 bytes) - For use with JDK 1.4
    classes12.jar - JDBC classes (1,234,433bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.jar - JDBC classes (1,063,074 bytes) - For use with JDK 1.1
  • Oracle9i 9.2.0.5 JDBC Drivers
    ojdbc14.jar - JDBC classes (1,200,046 bytes) - For use with JDK 1.4
    classes12.zip - JDBC classes (1,232,604 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes (1,063,479bytes) - For use with JDK 1.1
  • Oracle9i 9.2.0.4 JDBC Drivers
    ojdbc14.jar - JDBC classes (1,187,584 bytes) - For use with JDK 1.4
    classes12.zip - JDBC classes (1,219,950 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes (1,052,833 bytes) - For use with JDK 1.1
  • Oracle9i 9.2.0.3 JDBC Drivers
    ojdbc14.jar - JDBC classes (1,181,679 bytes) - For use with JDK 1.4
    classes12.zip - JDBC classes (1,213,897 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes (1,048,261 bytes) - For use with JDK 1.1
  • Oracle9i 9.2.0.1 JDBC Drivers
    ojdbc14.jar - JDBC classes ( 1,174,976 bytes) - For use with JDK 1.4
    classes12.zip - JDBC classes ( 1,207,068 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes ( 1,043,528 Bytes) - For use with JDK 1.1
  • Oracle9i 9.0.1.4 JDBC Drivers
    classes12.zip - JDBC classes (1,143,559 bytes) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes (988,625 bytes) - For use with JDK 1.1
  • Oracle9i 9.0.1 JDBC Drivers
    classes12.zip - JDBC classes( 1,081 kb) - For use with JDK 1.2 and JDK 1.3
    classes111.zip - JDBC classes ( 936 kB) - For use with JDK 1.1
  • Oracle8i 8.1.7.1JDBC Drivers
    classes12.zip - JDBC classes ( 1,892 kB) - For use with JDK 1.2
    classes111.zip - JDBC classes ( 1,741 kB)

Microsoft SQL Server JDBC Driver

2008을 지원한다기 보다 jdbc 4.0을 지원하는 거다.
SQL Server JDBC Driver 2.0 Documentation
http://msdn.microsoft.com/ko-kr/library/bb418447%28v=SQL.10%29.aspx

JDBC 드라이버 시스템 요구 사항
http://msdn.microsoft.com/ko-kr/library/ms378422%28v=SQL.100%29.aspx


- MS Driver


  • 이 드라이버는 아마도 SQL Server 2000 드라이버.
  • com.microsoft.jdbc.sqlserver.SQLServerDriver
  • jdbc:microsoft:sqlserver://ADDRESS:1433
  • mssqlserver.jar 와 com/microsoft/jdbc/base/BaseDriver 을 필요로 한다.

- jTDS
  • http://jtds.sourceforge.net
  • net.sourceforge.jtds.jdbc.Driver
  • jdbc:jtds:sqlserver://ADDRESS:1433/DB_NAME
  • jtds-1.2.2.jar
  • TEXT 컬럼 처리 가능

=-=> ms 드라이버는 text 컬럼처리 안되는게 있을거야.

- Windows 통합인증을 사용할 때는 sqljdbc_auth.dll이 필요 ==???


MySQL JDBC Driver

- MySQL Connector/J
  • MySQL Connectors
  • com.mysql.jdbc.Driver
  • jdbc:mysql://ADDRESS/DB_NAME?Unicode=true&characterEncoding=EUC_KR
  • mysql-connector-java-5.1.0-bin.jar(554KB)

JDBC Code Template - 프로시저

CallableStatement cs = null;
try{
    cs = con.prepareCall("{ ? = call sp_test(?,?,?) }");
    int idx = 0;
    cs.registerOutParameter(++idx, Types.INTEGER);
    cs.setString(++idx, COL_1);
    cs.setString(++idx, COL_2);
    cs.setString(++idx, COL_3);
    
    cs.execute();
    int result = cs.getInt(1);
    if(result == -1){ //check error
        throw new SQLException("result is -1"); //=-=> 좀 더 정형화된 다른 예외를 만들어야...
    }
    return result;

}catch(Exception e){  
    throw new RuntimeSQLException(e, primaryKey); 
}finally{
    if(cs != null){ try{ cs.close(); }catch(Exception ignored){  } }
}

JDBC Code Template


PreparedStatement ps = null;
try{
    ps = con.prepareStatement(QUERY);
    int idx = 0;
    ps.setString(++idx, COL_1);
    ...
    ps.setString(++idx, COL_N);
    
    return ps.executeUpdate();

}catch(Exception e){
    throw new RuntimeSQLException(e, primaryKey);
}finally{
    if(ps != null){ try{ ps.close(); }catch(Exception ignored){  }
}
Connection con = null;
PrepareStatement ps = null;

try{
	ps = con.prepareStatement(QUERY);  
	int idx = 0;  
	ps.setString(++idx, COL_1);  
	...  
	ps.setString(++idx, COL_N);  

	int affectedRow = ps.executeUpdate();
	if(affectedRow != 1){
		throw new RuntimeSQLException(" expected : 1, result : " + affectedRow
			, primaryKey); //=-=> 정형화...
	}
	con.commit();
}catch(Exception e){
	con.rollback();
	throw new RuntimeSQLException(e, primaryKey);
}finally{
    if(ps != null){ try{ ps.close(); }catch(Exception ignored){  }
    if(con != null){ try{ con.close(); }catch(Exception ignored){  }
}

해서는 안되는 예외 처리 - 아무것도 안하는 경우

예외를 잡아서 아무것도 처리하지 않는 경우 예외가 발생했는지도 모르기 때문에 유지보수가 힘들다.
필요한 경우가 아닌 경우 절대 해서는 안되는 방식이다.
로그만 남기고 지나는 경우도 별반 다르지 않다.
사용자는 예외가 발생했는지 인지할수가 없다.
그냥 안된다고만 한다.
예외처리를 하더라도 로그는 남겨야 한다.(로그는 중앙집중적으로 한곳에서 남겨야 한다.)
에러났다고 하는데 원인을 파악할 수 없다.
  [todo] 적절한 예외 처리 를 정리할 것.

좋은 코딩 습관 - 리턴값 확인

자바는 예외로 처리할 수 있지만 C 언어같은 경우는 실행성공유무를 리턴값으로 돌려 준다.
이런 리턴값을 확인하지 않고 넘어가는 경우 디버깅하기가 힘들다.

SQL 관련 처리를 할때도 INSERT/UPDATE/DELETE 구문을 실행한 후에 삽입/수정/삭제된 개수를 알수 있다.
이 개수를 확인하지 않아서 프로그램에 구멍이 생기는 경우가 많다.
적용된 개수를 반드시 확인하도록 한다.

데이터 확인용 JSP/미완/spring/jndi추가

UPDATE/DELETE/INSERT 구문은 affectedRows 를 넘겨받아서 일치하는 경우만 commit 하도록 하자.
SELECT 시 로우개수를 제한할 것.


시스템 정보 조회용 JSP

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.