Your SlideShare is downloading. ×
0
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Refactoring Jdbc Programming
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Refactoring Jdbc Programming

3,102

Published on

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,102
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
66
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 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(
      • "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()
  • 13. 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()
  • 14. 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()
  • 15. 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()
  • 16. 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()
  • 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(
    • "select * from LECTURE where ID=?" ,
    • ...
    • }, 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 를 비롯한 각 담당자에게 위임
  • 33. 2. SPRING 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
  • 52. 감사합니다 .

×