SlideShare a Scribd company logo
Refactoring JDBC programming 2008.10.12 박찬욱
Hand-made JdbcTemplate 1.1  문제 인식 공유 1.2  해결 방안 모색 1.3 Refactoring with Strategy pattern Spring JdbcTemplate 2.1 Best Practice of JDBC Strategy 2.2 Simplify JDBC operation Table of Contents
오늘의 목표는 ? Composition + interface-based  프로그래밍 기법 Spring JdbcTemplate  이해하기 어디 쓸 만한 곳이 없을까 ?
1.  Hand-made JdbcTemplate
1.1  문제 인식 공유 퀴즈 iBatis ORM(Hibernate or TopLink  등 ) 내부 추상화 프레임웍 쌩 (pure) JDBC~?
1.1  문제 인식 공유 JDBC  근본적인 문제 TCFTC T ry- C atch- F inally- T ry- C atch 최고의  boilerplate  코드 Connection / Resource  누수 문제 SQLException 데이터베이스 벤더 별로 정의된  error code, error state  정보 Connection con = null;  Statement stmt = null;  try {  con = dataSource.getConnection();  stmt = con.createStatement();  stmt.executeUpdate(“UPDATE TABLE_NAME SET...”);  }c atch(SQLException e){ // 예외 처리 ... }finally {  if (stmt != null) { try { stmt.close(); }  catch (SQLException ex) {} }  if (con != null) try { con.close(); } catch (SQLException ex) { }  }
1.1  문제 인식 공유 전혀  OO  스럽지 않은 반복적인 코드 (boilerplate code) 의 사용으로  Data Access  코드가 드러워져 간다 “ Bad Java code is bad J2EE code.” - Rod Johnson
1.2  해결 방안 모색 Strategy pattern 을  도입해서  문제 해결  시도
1.2  해결 방안 모색 Strategy pattern  이란 ? 실행 시점에 (at runtime)  알고리즘을 선택할 수 있는 방법
1.2  해결 방안 모색 왜  Strategy pattern 을 택했나 ? Programming to  Interface  instead of Concrete Class (Achieving Loose Coupling with Interface) - Favor object  composition  over class inheritance  (Prefer Object Composition to Concrete Inheritance)
2.1 Best Practice of JDBC Strategy Strategy pattern 참조 : wiki[2]
1.3 Refactoring with Strategy pattern 변경되는 부분과 그렇지 않은 부분 식별하기 ,  각각 Updating sql  실행 try  { // get DB connection con =  getConnection(); // create Statement stmt = con.prepareStatement( "update LECTURE SET name=? where ID=?“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); }  catch  (SQLException exception) { //  예외처리 }  finally  { if  (stmt !=  null ) { try  { stmt.close();} catch (SQLException e){} } // end if if  (con !=  null ) { try  { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return  result; try  { // get DB connection con =  getConnection(); // create Statement stmt = con.prepareStatement( "insert into LECTURE values(?, ?, ?, ?, ?)“ ); // binding sql parameters stmt.setInt(1,  incrementer .nextIntValue()); // ... // execute Query result = stmt.executeUpdate(); }  catch  (SQLException exception) { //  예외처리 }  finally  { if  (stmt !=  null ) { try  { stmt.close();} catch (SQLException e){} } // end if if  (con !=  null ) { try  { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return  result; update() insert()
1.3 Refactoring with Strategy pattern try  { // get DB connection con =  getConnection(); // create Statement stmt = con.prepareStatement( "update LECTURE SET name=? where ID=?“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); }  catch  (SQLException exception) { //  예외처리 }  finally  { if  (stmt !=  null ) { try  { stmt.close();} catch (SQLException e){} } // end if if  (con !=  null ) { try  { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return  result; 메소드 인자로 빼냄 콜백 메소드로 구현 공통 메소드로 추출 update() insert()
1.3 Refactoring with Strategy pattern try  { // get DB connection con =  getConnection(); // create Statement stmt = con.prepareStatement( "update LECTURE SET name=? where ID=?“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); }  catch  (SQLException exception) { //  예외처리 }  finally  { if  (stmt !=  null ) { try  { stmt.close();} catch (SQLException e){} } // end if if  (con !=  null ) { try  { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return  result; update() insert()
1.3 Refactoring with Strategy pattern try  { // get DB connection con =  getConnection(); // create Statement stmt = con.prepareStatement( "update LECTURE SET name=? where ID=?“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); }  catch  (SQLException exception) { //  예외처리 }  finally  { if  (stmt !=  null ) { try  { stmt.close();} catch (SQLException e){} } // end if if  (con !=  null ) { try  { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return  result; update()
1.3 Refactoring with Strategy pattern try  { // get DB connection con =  getConnection(); // create Statement stmt = con.prepareStatement( " insert into LECTURE values(?, ?, ?, ?, ?)“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); }  catch  (SQLException exception) { //  예외처리 }  finally  { if  (stmt !=  null ) { try  { stmt.close();} catch (SQLException e){} } // end if if  (con !=  null ) { try  { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return  result; insert()
1.3 Refactoring with Strategy pattern Strategy pattern 이 적용된  Template.update()
1.3 Refactoring with Strategy pattern 변경되는 부분과 그렇지 않은 부분 식별하기 ,  각각 querying sql  실행 try  { // get DB connection con =  getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while  (rs.next()) { result =  new  Lecture(); Result.setName(rs.getString(2)); // extracting... } }  catch  (SQLException exception) { //  예외처리 }  finally  { //  자원 반환 처리 } return  result; try  { // get DB connection con =  getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE“ ); // binding sql parameter // execute Query rs = stmt.executeQuery(); //extract result while  (rs.next()) { lecture =  new  Lecture(); Result.setName(rs.getString(2)); // extracting... result.add(lecture); } }  catch  (SQLException exception) { //  예외처리 }  finally  { //  자원 반환 처리 } return  result; get() getall()
1.3 Refactoring with Strategy pattern try  { // get DB connection con =  getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while  (rs.next()) { result =  new  Lecture(); Result.setName(rs.getString(2)); // extracting... } }  catch  (SQLException exception) { //  예외처리 }  finally  { //  자원 반환 처리 } return  result; get() 메소드 인자로 빼냄 콜백 메소드로 구현 공통 메소드로 추출 getall()
1.3 Refactoring with Strategy pattern try  { // get DB connection con =  getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while  (rs.next()) { result =  new  Lecture(); Result.setName(rs.getString(2)); // extracting... } }  catch  (SQLException exception) { //  예외처리 }  finally  { //  자원 반환 처리 } return  result; get() getall()
1.3 Refactoring with Strategy pattern try  { // get DB connection con =  getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while  (rs.next()) { result =  new  Lecture(); Result.setName(rs.getString(2)); // extracting... } }  catch  (SQLException exception) { //  예외처리 }  finally  { //  자원 반환 처리 } return  result; getall()
1.3 Refactoring with Strategy pattern try  { // get DB connection con =  getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while  (rs.next()) { result =  new  Lecture(); Result.setName(rs.getString(2)); // extracting... } }  catch  (SQLException exception) { //  예외처리 }  finally  { //  자원 반환 처리 } return  result; get()
1.3 Refactoring with Strategy pattern Strategy pattern 이 적용된  Template.query()
1.3 Refactoring with Strategy pattern Refactoring 1. 결과 값의 타입은 ? ResultSet  처리 동일한  DTO 인 경우 ,  거의 동일하게  ResultSet 에서 값을 빼내는 코드가 반복됨 return  (Lecture)  template .query( &quot;select * from LECTURE where ID=?&quot; , ... },  new  ResultSetExtractor() { public  Object extractResult(ResultSet rs) throws  SQLException { // extract result to Single Object Lecture result =  new  Lecture(); while  (rs.next()) { result.setId(rs.getInt(1)); result.setName(rs.getString(2)); result.setSpeaker(rs.getString(3)); } return  result; } }); return  (List<Lecture>)  template .query( &quot;select * from LECTURE&quot; , ... },  new  ResultSetExtractor() { public  Object extractResult(ResultSet rs) throws  SQLException { // extract result to Collection Object List<Lecture> result =  new  ArrayList<Lecture>(); while  (rs.next()) { Lecture lecture =  new  Lecture(); lecture.setId(rs.getInt(1)); lecture.setName(rs.getString(2)); lecture.setSpeaker(rs.getString(3));   result.add(lecture); } return  result; } }); get() getall()
1.3 Refactoring with Strategy pattern return  (Lecture)  template .query( &quot;select * from LECTURE where ID=?&quot; , ... },  new  ResultSetExtractor() { public  Object extractResult(ResultSet rs) throws  SQLException { // extract result to Single Object Lecture result =  new  Lecture(); while  (rs.next()) { result.setId(rs.getInt(1)); result.setName(rs.getString(2)); result.setSpeaker(rs.getString(3)); } return  result; } }); get() 콜백 메소드로 구현 API 로 구분
1.3 Refactoring with Strategy pattern return  (Lecture)  template .query( &quot;select * from LECTURE where ID=?&quot; , ... },  new  ResultSetExtractor() { public  Object extractResult(ResultSet rs) throws  SQLException { // extract result to Single Object Lecture result =  new  Lecture(); while  (rs.next()) { result.setId(rs.getInt(1)); result.setName(rs.getString(2)); result.setSpeaker(rs.getString(3)); } return  result; } }); get()
1.3 Refactoring with Strategy pattern return  (Lecture)  template .query( &quot;select * from LECTURE where ID=?&quot; , ... },  new  ResultSetExtractor() { public  Object extractResult(ResultSet rs) throws  SQLException { // extract result to Single Object Lecture result =  new  Lecture(); while  (rs.next()) { result.setId(rs.getInt(1)); result.setName(rs.getString(2)); result.setSpeaker(rs.getString(3)); } return  result; } }); get()
1.3 Refactoring with Strategy pattern Refactoring 2. 여전히  Template 의  query() 와  update() 에서  JDBC API 가 중복되어 사용된다 !
1.3 Refactoring with Strategy pattern Refactoring 2.  결과
1.3 Refactoring with Strategy pattern 콜백 인터페이스가 적용된 공통 메소드
1.4 Summary 구현한 템플릿 클래스와 인터페이스
1.4 Summary JdbcTemplate  도입된 이후의 효과 JDBC workflow 의 흐름 진행 주체 DAO    JdbcTemplate DAO 의 역할 충실화 SQL,  파라미터 제공  or  결과 매핑 이 외의 다른 역할은  JdbcTemplate 를 비롯한 각 담당자에게 위임
2. SPRING JDBCTEMPLATE
2.1 Best Practice of JDBC Strategy Spring JDBC core package’s Central class Jdbc UseCase Best Practice Collaborate with Various Callback Interface    Strategy pattern ! Convenience DA operation &quot;This is  a special case of the Strategy design pattern .  It appears different because  the interface involved  are so simple &quot;
2.1 Best Practice of JDBC Strategy JdbcTemplate with Strategy pattern DAO Template Callback Interface implementation 참조 : wiki[2]
2.1 Best Practice of JDBC Strategy Jdbc-based DAO Spring-based DAO DriverManager / DataSource DataSource Statement / PreparedStatement / CallableStatement JdbcTemplate / Callback interface ResultSet  POJO / POJO’s collection
2.1 Best Practice of JDBC Strategy Task Spring You Connection(DataSource) management Provide SQL Statement management Parameter Declaration Provide parameter value ResultSet management Row Data Retrieval Transaction management Exception handling
2.1 Best Practice of JDBC Strategy Convenience , but  powerful  Jdbc Template Resource management DataSourceUtils Integrated with Transaction management Spring-tx (non-invasive)
2.1 Best Practice of JDBC Strategy Convenience , but  powerful  JdbcTemplate Consistent exception management 예외 발생 시 처리 기준 에러 코드 (error code),  에러 상태 (error state)    예외 종류 (type of Exception) Check exception    Unchecked exception SQLExceptionTranslator
2.1 Best Practice of JDBC Strategy Convenience , but  powerful  JdbcTemplate Logging for SQL inform. (DEBUG level) Various Template JdbcTemplate NamedParameterJdbcTemplate SimpleJdbcTemplate Convenience DA operation named parameter Auto-detect column by Jdbc Driver Easily using Batch, LOB
2.1 Best Practice of JDBC Strategy JdbcTemplate  구성 방법 DataSource(or Connection Pool) 가 쓰레드 안전하다면 , JdbcTemplate 도 쓰레드 안전 private  JdbcTemplate  template ; public   void  setTemplate(DataSource dataSource) { this . template  =  new  JdbcTemplate(dataSource); } < bean  id = &quot;lectureDao&quot;  class = &quot;org.springframework.lecture.jdbc.dao.JdbcLectureDao&quot; > < property  name = &quot;template&quot;  ref = &quot;dataSource&quot;  /> </ bean > private  JdbcTemplate  template ; public   void  setTemplate(JdbcTemplate template) { this . template  = template; } < bean  id = &quot;lectureDao&quot;  class = &quot;org.springframework.lecture.jdbc.dao.JdbcLectureDao&quot; > < property  name = &quot;template&quot;  ref = &quot;jdbcTemplate&quot;  /> </ bean >
2.2 SIMPLIFY JDBC OPERATION
2.2 Simplify JDBC operation SimpleJdbc*  활용하기 SimpleJdbcTemplate Wrapper around classic JdbcTemplate class(getJdbcOperations()) Java-5-based convenience wrapper for the classic Spring  JdbcTemplate Varargs, Generic, Autoboxing, Unboxing...
2.2 Simplify JDBC operation SimpleJdbc*  활용하기 SimpleJdbcInsert Simplify Insert behavior JdbcTemplate + DatabaseMetaData ‘ fluid’ interface style
2.2 Simplify JDBC operation SimpleJdbc*  활용하기 SimpleJdbcCall multi-threaded, reusable object representing a call to stored procedure or a stored function SimpleJdbcTestUtils
2.2 Simplify JDBC operation The  Pareto Principle  in action JdbcTemplate+callback interface by Reflection = 80 SqlQuery + inheritance by explicit parameter mapping =20
2.2 Simplify JDBC operation RowMapper(with ResultSetExtractor) per-row basis Stateless & reusable Ideal choice of row-mapping logic ResultSetExtractor per-resultSet basis Stateless & reusable, if not access stateful resource
2.2 Simplify JDBC operation SqlQuery by Inheritance Reusable, threadsafe class Encapsulate SQL MappingSqlQuery & UpdatableSqlQuery Using meaningful method name
2.2 Simplify JDBC operation RowCallbackHandler Stateful public void processRow(ResultSet rs) throws SQLException
2.2 Simplify JDBC operation DataFieldMaxValueIncrementer  활용하기 Sequence-based Oracle, PostgreSQL, DB2(plain, mainframe), HSQL, H2 Column-based MySQL, MS-SqlServer, Sybase, Hsql, Derby BeanProperty*  활용하기 (Parameterized)BeanPropertyRowMapper BeanPropertySqlParameterSource
Reference wiki[1]:  http://en.wikipedia.org/wiki/Image:Strategy_Pattern_Diagram_ZP.svg wiki[2]:  http://en.wikipedia.org/wiki/Image:Strategy_pattern_in_LePUS3.gif Tomas[1]: JDBC Development with the Spring Framework Spring reference Spring API J2EE Design and Development J2EE without EJB
감사합니다 .

More Related Content

PDF
追求Jdbc on oracle最佳性能?如何才好?
ODP
Jersey Guice AOP
DOCX
Exercícios Netbeans - Vera Cymbron
KEY
How to Start Test-Driven Development in Legacy Code
PDF
C++ aptitude
PDF
Advanced Java Practical File
PPT
Executing Sql Commands
DOCX
Advance Java Programs skeleton
追求Jdbc on oracle最佳性能?如何才好?
Jersey Guice AOP
Exercícios Netbeans - Vera Cymbron
How to Start Test-Driven Development in Legacy Code
C++ aptitude
Advanced Java Practical File
Executing Sql Commands
Advance Java Programs skeleton

What's hot (20)

PPTX
重構—改善既有程式的設計(chapter 9)
DOCX
PDF
5. Ввод-вывод, доступ к файловой системе
PDF
COScheduler In Depth
DOC
Create a Customized GMF DnD Framework
PPTX
C++11 - STL Additions
PPTX
Pro typescript.ch03.Object Orientation in TypeScript
DOCX
Wwe Management System
PDF
spring-tutorial
PDF
3. Объекты, классы и пакеты в Java
DOC
12. stl örnekler
PPTX
分散式系統
PPTX
Oleksandr Valetskyy - DI vs. IoC
DOC
Converting Db Schema Into Uml Classes
PDF
Java_practical_handbook
PPTX
重構—改善既有程式的設計(chapter 8)part 2
PPTX
C++11 Multithreading - Futures
PPTX
重構—改善既有程式的設計(chapter 8)part 1
PPT
E:\Plp 2009 2\Plp 9
PPTX
PL/SQL User-Defined Functions in the Read World
重構—改善既有程式的設計(chapter 9)
5. Ввод-вывод, доступ к файловой системе
COScheduler In Depth
Create a Customized GMF DnD Framework
C++11 - STL Additions
Pro typescript.ch03.Object Orientation in TypeScript
Wwe Management System
spring-tutorial
3. Объекты, классы и пакеты в Java
12. stl örnekler
分散式系統
Oleksandr Valetskyy - DI vs. IoC
Converting Db Schema Into Uml Classes
Java_practical_handbook
重構—改善既有程式的設計(chapter 8)part 2
C++11 Multithreading - Futures
重構—改善既有程式的設計(chapter 8)part 1
E:\Plp 2009 2\Plp 9
PL/SQL User-Defined Functions in the Read World
Ad

Similar to Refactoring Jdbc Programming (10)

PDF
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
PPTX
비동기 회고 발표자료
PDF
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
PPT
Daejeon IT Developer Conference Web Service Practice
PDF
210428kopo
PDF
#36.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_재직자환급교육,실업자교육,국비지원교육, 자바교육,구...
PDF
자바 8 스트림 API
PDF
ORM을 맞이하는 우리의 자세
PPTX
What is persistence in java
PDF
Refactoring 메소드 호출의 단순화
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
비동기 회고 발표자료
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
Daejeon IT Developer Conference Web Service Practice
210428kopo
#36.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_재직자환급교육,실업자교육,국비지원교육, 자바교육,구...
자바 8 스트림 API
ORM을 맞이하는 우리의 자세
What is persistence in java
Refactoring 메소드 호출의 단순화
Ad

Recently uploaded (20)

PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Network Security Unit 5.pdf for BCA BBA.
PPT
Teaching material agriculture food technology
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
Cloud computing and distributed systems.
PDF
Modernizing your data center with Dell and AMD
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Advanced methodologies resolving dimensionality complications for autism neur...
NewMind AI Monthly Chronicles - July 2025
Network Security Unit 5.pdf for BCA BBA.
Teaching material agriculture food technology
Encapsulation_ Review paper, used for researhc scholars
Diabetes mellitus diagnosis method based random forest with bat algorithm
Chapter 3 Spatial Domain Image Processing.pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
Dropbox Q2 2025 Financial Results & Investor Presentation
Per capita expenditure prediction using model stacking based on satellite ima...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Cloud computing and distributed systems.
Modernizing your data center with Dell and AMD
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Digital-Transformation-Roadmap-for-Companies.pptx
MYSQL Presentation for SQL database connectivity
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...

Refactoring Jdbc Programming

  • 1. Refactoring JDBC programming 2008.10.12 박찬욱
  • 2. Hand-made JdbcTemplate 1.1 문제 인식 공유 1.2 해결 방안 모색 1.3 Refactoring with Strategy pattern Spring JdbcTemplate 2.1 Best Practice of JDBC Strategy 2.2 Simplify JDBC operation Table of Contents
  • 3. 오늘의 목표는 ? Composition + interface-based 프로그래밍 기법 Spring JdbcTemplate 이해하기 어디 쓸 만한 곳이 없을까 ?
  • 4. 1. Hand-made JdbcTemplate
  • 5. 1.1 문제 인식 공유 퀴즈 iBatis ORM(Hibernate or TopLink 등 ) 내부 추상화 프레임웍 쌩 (pure) JDBC~?
  • 6. 1.1 문제 인식 공유 JDBC 근본적인 문제 TCFTC T ry- C atch- F inally- T ry- C atch 최고의 boilerplate 코드 Connection / Resource 누수 문제 SQLException 데이터베이스 벤더 별로 정의된 error code, error state 정보 Connection con = null; Statement stmt = null; try { con = dataSource.getConnection(); stmt = con.createStatement(); stmt.executeUpdate(“UPDATE TABLE_NAME SET...”); }c atch(SQLException e){ // 예외 처리 ... }finally { if (stmt != null) { try { stmt.close(); } catch (SQLException ex) {} } if (con != null) try { con.close(); } catch (SQLException ex) { } }
  • 7. 1.1 문제 인식 공유 전혀 OO 스럽지 않은 반복적인 코드 (boilerplate code) 의 사용으로 Data Access 코드가 드러워져 간다 “ Bad Java code is bad J2EE code.” - Rod Johnson
  • 8. 1.2 해결 방안 모색 Strategy pattern 을 도입해서 문제 해결 시도
  • 9. 1.2 해결 방안 모색 Strategy pattern 이란 ? 실행 시점에 (at runtime) 알고리즘을 선택할 수 있는 방법
  • 10. 1.2 해결 방안 모색 왜 Strategy pattern 을 택했나 ? Programming to Interface instead of Concrete Class (Achieving Loose Coupling with Interface) - Favor object composition over class inheritance (Prefer Object Composition to Concrete Inheritance)
  • 11. 2.1 Best Practice of JDBC Strategy Strategy pattern 참조 : wiki[2]
  • 12. 1.3 Refactoring with Strategy pattern 변경되는 부분과 그렇지 않은 부분 식별하기 , 각각 Updating sql 실행 try { // get DB connection con = getConnection(); // create Statement stmt = con.prepareStatement( &quot;update LECTURE SET name=? where ID=?“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); } catch (SQLException exception) { // 예외처리 } finally { if (stmt != null ) { try { stmt.close();} catch (SQLException e){} } // end if if (con != null ) { try { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return result; try { // get DB connection con = getConnection(); // create Statement stmt = con.prepareStatement( &quot;insert into LECTURE values(?, ?, ?, ?, ?)“ ); // binding sql parameters stmt.setInt(1, incrementer .nextIntValue()); // ... // execute Query result = stmt.executeUpdate(); } catch (SQLException exception) { // 예외처리 } finally { if (stmt != null ) { try { stmt.close();} catch (SQLException e){} } // end if if (con != null ) { try { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return result; update() insert()
  • 13. 1.3 Refactoring with Strategy pattern try { // get DB connection con = getConnection(); // create Statement stmt = con.prepareStatement( &quot;update LECTURE SET name=? where ID=?“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); } catch (SQLException exception) { // 예외처리 } finally { if (stmt != null ) { try { stmt.close();} catch (SQLException e){} } // end if if (con != null ) { try { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return result; 메소드 인자로 빼냄 콜백 메소드로 구현 공통 메소드로 추출 update() insert()
  • 14. 1.3 Refactoring with Strategy pattern try { // get DB connection con = getConnection(); // create Statement stmt = con.prepareStatement( &quot;update LECTURE SET name=? where ID=?“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); } catch (SQLException exception) { // 예외처리 } finally { if (stmt != null ) { try { stmt.close();} catch (SQLException e){} } // end if if (con != null ) { try { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return result; update() insert()
  • 15. 1.3 Refactoring with Strategy pattern try { // get DB connection con = getConnection(); // create Statement stmt = con.prepareStatement( &quot;update LECTURE SET name=? where ID=?“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); } catch (SQLException exception) { // 예외처리 } finally { if (stmt != null ) { try { stmt.close();} catch (SQLException e){} } // end if if (con != null ) { try { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return result; update()
  • 16. 1.3 Refactoring with Strategy pattern try { // get DB connection con = getConnection(); // create Statement stmt = con.prepareStatement( &quot; insert into LECTURE values(?, ?, ?, ?, ?)“ ); // binding sql parameter stmt.setString(1, name); //... // execute Query result = stmt.executeUpdate(); } catch (SQLException exception) { // 예외처리 } finally { if (stmt != null ) { try { stmt.close();} catch (SQLException e){} } // end if if (con != null ) { try { con.close();} catch (SQLException e){} } // end if } // end try-catch-finally return result; insert()
  • 17. 1.3 Refactoring with Strategy pattern Strategy pattern 이 적용된 Template.update()
  • 18. 1.3 Refactoring with Strategy pattern 변경되는 부분과 그렇지 않은 부분 식별하기 , 각각 querying sql 실행 try { // get DB connection con = getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while (rs.next()) { result = new Lecture(); Result.setName(rs.getString(2)); // extracting... } } catch (SQLException exception) { // 예외처리 } finally { // 자원 반환 처리 } return result; try { // get DB connection con = getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE“ ); // binding sql parameter // execute Query rs = stmt.executeQuery(); //extract result while (rs.next()) { lecture = new Lecture(); Result.setName(rs.getString(2)); // extracting... result.add(lecture); } } catch (SQLException exception) { // 예외처리 } finally { // 자원 반환 처리 } return result; get() getall()
  • 19. 1.3 Refactoring with Strategy pattern try { // get DB connection con = getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while (rs.next()) { result = new Lecture(); Result.setName(rs.getString(2)); // extracting... } } catch (SQLException exception) { // 예외처리 } finally { // 자원 반환 처리 } return result; get() 메소드 인자로 빼냄 콜백 메소드로 구현 공통 메소드로 추출 getall()
  • 20. 1.3 Refactoring with Strategy pattern try { // get DB connection con = getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while (rs.next()) { result = new Lecture(); Result.setName(rs.getString(2)); // extracting... } } catch (SQLException exception) { // 예외처리 } finally { // 자원 반환 처리 } return result; get() getall()
  • 21. 1.3 Refactoring with Strategy pattern try { // get DB connection con = getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while (rs.next()) { result = new Lecture(); Result.setName(rs.getString(2)); // extracting... } } catch (SQLException exception) { // 예외처리 } finally { // 자원 반환 처리 } return result; getall()
  • 22. 1.3 Refactoring with Strategy pattern try { // get DB connection con = getConnection(); // create Statement rs = con.prepareStatement( “ select * from LECTURE where ID=?“ ); // binding sql parameter stmt.setInt(1, id); // execute Query rs = stmt.executeQuery(); //extract result while (rs.next()) { result = new Lecture(); Result.setName(rs.getString(2)); // extracting... } } catch (SQLException exception) { // 예외처리 } finally { // 자원 반환 처리 } return result; get()
  • 23. 1.3 Refactoring with Strategy pattern Strategy pattern 이 적용된 Template.query()
  • 24. 1.3 Refactoring with Strategy pattern Refactoring 1. 결과 값의 타입은 ? ResultSet 처리 동일한 DTO 인 경우 , 거의 동일하게 ResultSet 에서 값을 빼내는 코드가 반복됨 return (Lecture) template .query( &quot;select * from LECTURE where ID=?&quot; , ... }, new ResultSetExtractor() { public Object extractResult(ResultSet rs) throws SQLException { // extract result to Single Object Lecture result = new Lecture(); while (rs.next()) { result.setId(rs.getInt(1)); result.setName(rs.getString(2)); result.setSpeaker(rs.getString(3)); } return result; } }); return (List<Lecture>) template .query( &quot;select * from LECTURE&quot; , ... }, new ResultSetExtractor() { public Object extractResult(ResultSet rs) throws SQLException { // extract result to Collection Object List<Lecture> result = new ArrayList<Lecture>(); while (rs.next()) { Lecture lecture = new Lecture(); lecture.setId(rs.getInt(1)); lecture.setName(rs.getString(2)); lecture.setSpeaker(rs.getString(3)); result.add(lecture); } return result; } }); get() getall()
  • 25. 1.3 Refactoring with Strategy pattern return (Lecture) template .query( &quot;select * from LECTURE where ID=?&quot; , ... }, new ResultSetExtractor() { public Object extractResult(ResultSet rs) throws SQLException { // extract result to Single Object Lecture result = new Lecture(); while (rs.next()) { result.setId(rs.getInt(1)); result.setName(rs.getString(2)); result.setSpeaker(rs.getString(3)); } return result; } }); get() 콜백 메소드로 구현 API 로 구분
  • 26. 1.3 Refactoring with Strategy pattern return (Lecture) template .query( &quot;select * from LECTURE where ID=?&quot; , ... }, new ResultSetExtractor() { public Object extractResult(ResultSet rs) throws SQLException { // extract result to Single Object Lecture result = new Lecture(); while (rs.next()) { result.setId(rs.getInt(1)); result.setName(rs.getString(2)); result.setSpeaker(rs.getString(3)); } return result; } }); get()
  • 27. 1.3 Refactoring with Strategy pattern return (Lecture) template .query( &quot;select * from LECTURE where ID=?&quot; , ... }, new ResultSetExtractor() { public Object extractResult(ResultSet rs) throws SQLException { // extract result to Single Object Lecture result = new Lecture(); while (rs.next()) { result.setId(rs.getInt(1)); result.setName(rs.getString(2)); result.setSpeaker(rs.getString(3)); } return result; } }); get()
  • 28. 1.3 Refactoring with Strategy pattern Refactoring 2. 여전히 Template 의 query() 와 update() 에서 JDBC API 가 중복되어 사용된다 !
  • 29. 1.3 Refactoring with Strategy pattern Refactoring 2. 결과
  • 30. 1.3 Refactoring with Strategy pattern 콜백 인터페이스가 적용된 공통 메소드
  • 31. 1.4 Summary 구현한 템플릿 클래스와 인터페이스
  • 32. 1.4 Summary JdbcTemplate 도입된 이후의 효과 JDBC workflow 의 흐름 진행 주체 DAO  JdbcTemplate DAO 의 역할 충실화 SQL, 파라미터 제공 or 결과 매핑 이 외의 다른 역할은 JdbcTemplate 를 비롯한 각 담당자에게 위임
  • 34. 2.1 Best Practice of JDBC Strategy Spring JDBC core package’s Central class Jdbc UseCase Best Practice Collaborate with Various Callback Interface  Strategy pattern ! Convenience DA operation &quot;This is a special case of the Strategy design pattern . It appears different because the interface involved are so simple &quot;
  • 35. 2.1 Best Practice of JDBC Strategy JdbcTemplate with Strategy pattern DAO Template Callback Interface implementation 참조 : wiki[2]
  • 36. 2.1 Best Practice of JDBC Strategy Jdbc-based DAO Spring-based DAO DriverManager / DataSource DataSource Statement / PreparedStatement / CallableStatement JdbcTemplate / Callback interface ResultSet POJO / POJO’s collection
  • 37. 2.1 Best Practice of JDBC Strategy Task Spring You Connection(DataSource) management Provide SQL Statement management Parameter Declaration Provide parameter value ResultSet management Row Data Retrieval Transaction management Exception handling
  • 38. 2.1 Best Practice of JDBC Strategy Convenience , but powerful Jdbc Template Resource management DataSourceUtils Integrated with Transaction management Spring-tx (non-invasive)
  • 39. 2.1 Best Practice of JDBC Strategy Convenience , but powerful JdbcTemplate Consistent exception management 예외 발생 시 처리 기준 에러 코드 (error code), 에러 상태 (error state)  예외 종류 (type of Exception) Check exception  Unchecked exception SQLExceptionTranslator
  • 40. 2.1 Best Practice of JDBC Strategy Convenience , but powerful JdbcTemplate Logging for SQL inform. (DEBUG level) Various Template JdbcTemplate NamedParameterJdbcTemplate SimpleJdbcTemplate Convenience DA operation named parameter Auto-detect column by Jdbc Driver Easily using Batch, LOB
  • 41. 2.1 Best Practice of JDBC Strategy JdbcTemplate 구성 방법 DataSource(or Connection Pool) 가 쓰레드 안전하다면 , JdbcTemplate 도 쓰레드 안전 private JdbcTemplate template ; public void setTemplate(DataSource dataSource) { this . template = new JdbcTemplate(dataSource); } < bean id = &quot;lectureDao&quot; class = &quot;org.springframework.lecture.jdbc.dao.JdbcLectureDao&quot; > < property name = &quot;template&quot; ref = &quot;dataSource&quot; /> </ bean > private JdbcTemplate template ; public void setTemplate(JdbcTemplate template) { this . template = template; } < bean id = &quot;lectureDao&quot; class = &quot;org.springframework.lecture.jdbc.dao.JdbcLectureDao&quot; > < property name = &quot;template&quot; ref = &quot;jdbcTemplate&quot; /> </ bean >
  • 42. 2.2 SIMPLIFY JDBC OPERATION
  • 43. 2.2 Simplify JDBC operation SimpleJdbc* 활용하기 SimpleJdbcTemplate Wrapper around classic JdbcTemplate class(getJdbcOperations()) Java-5-based convenience wrapper for the classic Spring JdbcTemplate Varargs, Generic, Autoboxing, Unboxing...
  • 44. 2.2 Simplify JDBC operation SimpleJdbc* 활용하기 SimpleJdbcInsert Simplify Insert behavior JdbcTemplate + DatabaseMetaData ‘ fluid’ interface style
  • 45. 2.2 Simplify JDBC operation SimpleJdbc* 활용하기 SimpleJdbcCall multi-threaded, reusable object representing a call to stored procedure or a stored function SimpleJdbcTestUtils
  • 46. 2.2 Simplify JDBC operation The Pareto Principle in action JdbcTemplate+callback interface by Reflection = 80 SqlQuery + inheritance by explicit parameter mapping =20
  • 47. 2.2 Simplify JDBC operation RowMapper(with ResultSetExtractor) per-row basis Stateless & reusable Ideal choice of row-mapping logic ResultSetExtractor per-resultSet basis Stateless & reusable, if not access stateful resource
  • 48. 2.2 Simplify JDBC operation SqlQuery by Inheritance Reusable, threadsafe class Encapsulate SQL MappingSqlQuery & UpdatableSqlQuery Using meaningful method name
  • 49. 2.2 Simplify JDBC operation RowCallbackHandler Stateful public void processRow(ResultSet rs) throws SQLException
  • 50. 2.2 Simplify JDBC operation DataFieldMaxValueIncrementer 활용하기 Sequence-based Oracle, PostgreSQL, DB2(plain, mainframe), HSQL, H2 Column-based MySQL, MS-SqlServer, Sybase, Hsql, Derby BeanProperty* 활용하기 (Parameterized)BeanPropertyRowMapper BeanPropertySqlParameterSource
  • 51. Reference wiki[1]: http://en.wikipedia.org/wiki/Image:Strategy_Pattern_Diagram_ZP.svg wiki[2]: http://en.wikipedia.org/wiki/Image:Strategy_pattern_in_LePUS3.gif Tomas[1]: JDBC Development with the Spring Framework Spring reference Spring API J2EE Design and Development J2EE without EJB