Table A (group by 한 값들이 모두 들어있는 테이블) select '1' from dual union all select '2' from dual union all select '3' from dual union all select '4' from dual union all
Table B (실제 값 가져오는 쿼리)
이런 식으로 group by 했을 때 무조건 나와서 통계 표와 맞춰야 하는 값들 강제 작성 후 left join
왜 프레임워크를 안 쓰는지 모르겠으나 ㅠㅠ 쌩 java로만 돌리는 환경. 대량 조회 하는 SQL을 thread까지 사용해서 동시에 돌리니 기존에 잘 돌아가던 쿼리도 executeQuery 부분에서 OutOfMemory가 발생함ㅠㅠ
생각한 해결책 1. executeQuery의 Fetch Size 조절(현재는 40,000건씩 fetch) 2. mybatis 프레임워크 도입(Spring을 이용한 mybatis 정보는 상당히 많음 ㅠㅠ)
일단 급한 불부터 꺼야 했기에 1번 해결책으로 Fetch 사이즈를 조절해보았다. 10,000건으로 줄여보았는데도 똑같이 Heap space 에러가 발생하였다. 근데 default fetch를 쓰자니 10건씩이고...10배만 늘리자 타협하여 100건씩 fetch하니 일단은 잘 돌아간다. 하지만, 지금까지 대량건 조회는 Spring에서 rowhandler를 써왔기에 java 코드 안에 SQL이 들어가 있어서 관리하기도 불편해서 이번 기회에 java mybatis without Spring 을 도입해보기로 했다.
오류 내용 - AbstractMethodError : Method oracle/jdbc/driver/OracleResultSetImpl.isClosed()Z is abstract Exception in thread "main" java.lang.AbstractMethodError: Method oracle/jdbc/driver/OracleResultSetImpl.isClosed()Z is abstract at oracle.jdbc.driver.OracleResultSetImpl.isClosed(OracleResultSetImpl.java) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.ibatis.logging.jdbc.ResultSetLogger.invoke(ResultSetLogger.java:68) at cohttp://m.sun.proxy.$Proxy2.isClosed(Unknown Source) at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:364) at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:337) at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:310) at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:202) at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:66) at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:80) at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:65) at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:90) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:75) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:69) at dao.(~~~~~). (~~~~~) ( (~~~~~) .java:9) at logic.Main.main(Main.java:74)
메이븐 리포지토리에 들어가 ojdbc6.jar 다운로드 후 jar파일 적용하니 mybatis로 쿼리가 동작한다! (처음부터 rowhandler를 만들면서 테스트 하기엔 무리라고 판단되어 정말 간단한 select 1 from dual 쿼리로 조회)
File list 1. xml 패키지 밑에 mybatis-config.xml (원하는 이름으로 해도 되는지는 추후 확인 필요) 2. sqlMappers 패키지 밑에 "원하는이름"-mapper.xml (SQL 작성 파일) 3. database 패키지 밑에 "원하는이름" .java (getSqlSession() 메소드 존재) 4. dao 패키지 밑에 "원하는이름" .java(mapper id로 쿼리 실행)
select count(case when ~~~~ then 1 end ) as column1 , count(case when ~~~~ then 1 end ) as column2 ,count(case when ~~~~ then 1 end )as column3 from 테이블명
Exception in thread "main"com.microsoft.sqlserver.jdbc.SQLServerException: "encrypt" 속성이 "true"(으)로 설정되고 "trustServerCertificate" 속성이 "false"(으)로 설정되었지만 드라이버가 SSL(Secure Sockets Layer) 암호화를 사용하여 SQL Server에 대한 보안 연결을 설정할 수 없습니다. 오류:sun.security.validator.ValidatorException: PKIX path building failed:sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. ClientConnectionId:14656c10-20ff-4388-924f-fba7692ec81e at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:4026) at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1954) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:3552) at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:3172) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:3014) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1836) at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnectionInternal(SQLServerDataSource.java:1489) at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnection(SQLServerDataSource.java:99) at database.SQLServerLMSDbConn.getConnection(SQLServerLMSDbConn.java:20) at database.DBConnectionFactory.<init>(DBConnectionFactory.java:15) at database.Main.main(Main.java:21) Caused by:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException: PKIX path building failed:sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1497) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:212) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1843) ... 9 more Caused by:sun.security.validator.ValidatorException: PKIX path building failed:sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:105) at com.microsoft.sqlserver.jdbc.HostNameOverrideX509TrustManager.checkServerTrusted(SQLServerTrustManager.java:88) at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:922) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1479) ... 17 more Caused by:sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145) at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ... 25 more
시스템 모니터링 자동화를 하며 지난 번에 구축한 SQL Server LMS 발송 DB와 내가 만든 모니터링 자동화 프로그램을 연결시켜보려고 했다. 그러나 연동 테스트 시 아래와 같은 오류가 발생하였다.
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/microsoft/sqlserver/jdbc/SQLServerDataSource has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:760) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) at java.net.URLClassLoader.access$100(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:368) at java.net.URLClassLoader$1.run(URLClassLoader.java:362) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:361) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at database.SQLServerLMSDbConn.getConnection(SQLServerLMSDbConn.java:12) at database.DBConnectionFactory.<init>(DBConnectionFactory.java:15) at database.Main.main(Main.java:21)
필요사항 - 로직 소스는 최대한 건드리지 않고 내가 필요한 DB connection을 어떤 DB든지 쉽게 갖다 쓰고 싶다.