SlideShare a Scribd company logo
한국 스프링 사용자 모임 (http://ksug.org) 1
Refactoring JDBC programming
2008.10.12
박찬욱
한국 스프링 사용자 모임 (http://ksug.org) 2
1. Hand-made JdbcTemplate
1.1 문제 인식 공유
1.2 해결 방안 모색
1.3 Refactoring with Strategy pattern
2. Spring JdbcTemplate
2.1 Best Practice of JDBC Strategy
2.2 Simplify JDBC operation
Table of Contents
한국 스프링 사용자 모임 (http://ksug.org) 3
오늘의 목표는 ?
• Composition + interface-based 프로그
래밍 기법
 Spring JdbcTemplate 이해하기
 어디 쓸 만한 곳이 없을까 ?
4한국 스프링 사용자 모임 (http://ksug.org)
1. Hand-made JdbcTemplate
한국 스프링 사용자 모임 (http://ksug.org) 5
1.1 문제 인식 공유
• 퀴즈
– iBatis
– ORM(Hibernate or TopLink 등 )
– 내부 추상화 프레임웍
– 쌩 (pure) JDBC~?
한국 스프링 사용자 모임 (http://ksug.org) 6
1.1 문제 인식 공유
• JDBC 근본적인 문제
– TCFTC
• Try-Catch-Finally-Try-Catch
• 최고의 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...”);
}catch(SQLException e){
// 예외 처리 ...
}finally {
if (stmt != null) { try { stmt.close(); } catch (SQLException ex) {} }
if (con != null) try { con.close(); } catch (SQLException ex) { }
}
한국 스프링 사용자 모임 (http://ksug.org) 7
1.1 문제 인식 공유
• 전혀 OO 스럽지 않은 반복적인 코드 (boilerplate code) 의 사용
으로 Data Access 코드가 드러워져 간다
“Bad Java code is bad J2EE code.”
- Rod Johnson
한국 스프링 사용자 모임 (http://ksug.org) 8
1.2 해결 방안 모색
Strategy
pattern 을
도입해서
문제 해결
시도
한국 스프링 사용자 모임 (http://ksug.org) 9
1.2 해결 방안 모색
• Strategy pattern 이란 ?
– 실행 시점에 (at runtime) 알고리즘을 선택할 수 있는 방
법
한국 스프링 사용자 모임 (http://ksug.org) 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)
한국 스프링 사용자 모임 (http://ksug.org) 11
2.1 Best Practice of JDBC Strategy
• Strategy pattern
참조 : wiki[2]
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 17
1.3 Refactoring with Strategy pattern
• Strategy pattern 이 적용된 Template.update()
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 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()
한국 스프링 사용자 모임 (http://ksug.org) 23
1.3 Refactoring with Strategy pattern
• Strategy pattern 이 적용된 Template.query()
한국 스프링 사용자 모임 (http://ksug.org) 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(
"select * from LECTURE",
...
}, 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()
한국 스프링 사용자 모임 (http://ksug.org) 25
1.3 Refactoring with Strategy pattern
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;
}
});
get()
콜백 메소드로 구현
API 로 구분
한국 스프링 사용자 모임 (http://ksug.org) 26
1.3 Refactoring with Strategy pattern
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;
}
});
get()
한국 스프링 사용자 모임 (http://ksug.org) 27
1.3 Refactoring with Strategy pattern
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;
}
});
get()
한국 스프링 사용자 모임 (http://ksug.org) 28
1.3 Refactoring with Strategy pattern
• Refactoring 2.
– 여전히 Template 의 query() 와 update() 에서 JDBC API
가 중복되어 사용된다 !
한국 스프링 사용자 모임 (http://ksug.org) 29
1.3 Refactoring with Strategy pattern
• Refactoring 2. 결과
한국 스프링 사용자 모임 (http://ksug.org) 30
1.3 Refactoring with Strategy pattern
• 콜백 인터페이스가 적용된 공통 메소드
한국 스프링 사용자 모임 (http://ksug.org) 31
1.4 Summary
• 구현한 템플릿 클래스와 인터페이스
한국 스프링 사용자 모임 (http://ksug.org) 32
1.4 Summary
• JdbcTemplate 도입된 이후의 효과
– JDBC workflow 의 흐름 진행 주체
• DAO  JdbcTemplate
– DAO 의 역할 충실화
• SQL, 파라미터 제공 or 결과 매핑
• 이 외의 다른 역할은 JdbcTemplate 를 비롯한 각 담당자에게 위임
한국 스프링 사용자 모임 (http://ksug.org) 33
2. SPRING JDBCTEMPLATE
한국 스프링 사용자 모임 (http://ksug.org) 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
"This is a special case of the Strategy design pattern.
It appears different because the interface involved
are so simple"
한국 스프링 사용자 모임 (http://ksug.org) 35
2.1 Best Practice of JDBC Strategy
• JdbcTemplate with Strategy pattern
DAO
Template
Callback
Interface
implementation
참조 : wiki[2]
한국 스프링 사용자 모임 (http://ksug.org) 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
한국 스프링 사용자 모임 (http://ksug.org) 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
한국 스프링 사용자 모임 (http://ksug.org) 38
2.1 Best Practice of JDBC Strategy
• Convenience, but powerful Jdbc Template
– Resource management
• DataSourceUtils
– Integrated with Transaction management
• Spring-tx (non-invasive)
한국 스프링 사용자 모임 (http://ksug.org) 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
한국 스프링 사용자 모임 (http://ksug.org) 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
한국 스프링 사용자 모임 (http://ksug.org) 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="lectureDao"
class="org.springframework.lecture.jdbc.dao.JdbcLectureDao">
<property name="template" ref="dataSource" />
</bean>
private JdbcTemplate template;
public void setTemplate(JdbcTemplate template) {
this.template = template;
}
<bean id="lectureDao"
class="org.springframework.lecture.jdbc.dao.JdbcLectureDao">
<property name="template" ref="jdbcTemplate" />
</bean>
한국 스프링 사용자 모임 (http://ksug.org) 42
2.2 SIMPLIFY JDBC OPERATION
한국 스프링 사용자 모임 (http://ksug.org) 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...
한국 스프링 사용자 모임 (http://ksug.org) 44
2.2 Simplify JDBC operation
• SimpleJdbc* 활용하기
– SimpleJdbcInsert
• Simplify Insert behavior
• JdbcTemplate + DatabaseMetaData
• ‘fluid’ interface style
한국 스프링 사용자 모임 (http://ksug.org) 45
2.2 Simplify JDBC operation
• SimpleJdbc* 활용하기
– SimpleJdbcCall
• multi-threaded, reusable object representing a call to
stored procedure or a stored function
– SimpleJdbcTestUtils
한국 스프링 사용자 모임 (http://ksug.org) 46
2.2 Simplify JDBC operation
• The Pareto Principle in action
– JdbcTemplate+callback interface by Reflection = 80
– SqlQuery + inheritance by explicit parameter mapping
=20
한국 스프링 사용자 모임 (http://ksug.org) 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
한국 스프링 사용자 모임 (http://ksug.org) 48
2.2 Simplify JDBC operation
• SqlQuery
– by Inheritance
– Reusable, threadsafe class
– Encapsulate SQL
– MappingSqlQuery & UpdatableSqlQuery
– Using meaningful method name
한국 스프링 사용자 모임 (http://ksug.org) 49
2.2 Simplify JDBC operation
• RowCallbackHandler
– Stateful
– public void processRow(ResultSet rs) throws
SQLException
한국 스프링 사용자 모임 (http://ksug.org) 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
한국 스프링 사용자 모임 (http://ksug.org) 51
Reference
• wiki[1]:
http://en.wikipedia.org/wiki/Image:Strategy_Pattern_Diagram_ZP
• wiki[2]:
http://en.wikipedia.org/wiki/Image:Strategy_pattern_in_LePUS3.g
• Tomas[1]: JDBC Development with the Spring Framework
• Spring reference
• Spring API
• J2EE Design and Development
• J2EE without EJB
한국 스프링 사용자 모임 (http://ksug.org) 52
감사합니다
.

More Related Content

What's hot

I got 99 problems, but ReST ain't one
I got 99 problems, but ReST ain't oneI got 99 problems, but ReST ain't one
I got 99 problems, but ReST ain't one
Adrian Cole
 
Working with Databases and MySQL
Working with Databases and MySQLWorking with Databases and MySQL
Working with Databases and MySQL
Nicole Ryan
 
Low Code Integration with Apache Camel.pdf
Low Code Integration with Apache Camel.pdfLow Code Integration with Apache Camel.pdf
Low Code Integration with Apache Camel.pdf
Claus Ibsen
 
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
PgDay.Seoul
 
Modern Java web applications with Spring Boot and Thymeleaf
Modern Java web applications with Spring Boot and ThymeleafModern Java web applications with Spring Boot and Thymeleaf
Modern Java web applications with Spring Boot and Thymeleaf
LAY Leangsros
 
JSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked DataJSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked Data
Gregg Kellogg
 
Intro to Cypher
Intro to CypherIntro to Cypher
Intro to Cypher
Neo4j
 
React.js 세미나
React.js 세미나React.js 세미나
React.js 세미나
Briantina
 
MySql Triggers Tutorial - The Webs Academy
MySql Triggers Tutorial - The Webs AcademyMySql Triggers Tutorial - The Webs Academy
MySql Triggers Tutorial - The Webs Academy
thewebsacademy
 
MongoDB
MongoDBMongoDB
9. index and index organized table
9. index and index organized table9. index and index organized table
9. index and index organized table
Amrit Kaur
 
HTTP and Your Angry Dog
HTTP and Your Angry DogHTTP and Your Angry Dog
HTTP and Your Angry Dog
Ross Tuck
 
Angular
AngularAngular
Angular
LearningTech
 
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트) 마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
Amazon Web Services Korea
 
Back to Basics 1: Thinking in documents
Back to Basics 1: Thinking in documentsBack to Basics 1: Thinking in documents
Back to Basics 1: Thinking in documents
MongoDB
 
Migrating from RDBMS to MongoDB
Migrating from RDBMS to MongoDBMigrating from RDBMS to MongoDB
Migrating from RDBMS to MongoDB
MongoDB
 
Laravel introduction
Laravel introductionLaravel introduction
Laravel introduction
Simon Funk
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
Dmitry Sheiko
 
jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...
jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...
jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...
Edureka!
 
Database Change Management as a Service
Database Change Management as a ServiceDatabase Change Management as a Service
Database Change Management as a Service
Andrew Solomon
 

What's hot (20)

I got 99 problems, but ReST ain't one
I got 99 problems, but ReST ain't oneI got 99 problems, but ReST ain't one
I got 99 problems, but ReST ain't one
 
Working with Databases and MySQL
Working with Databases and MySQLWorking with Databases and MySQL
Working with Databases and MySQL
 
Low Code Integration with Apache Camel.pdf
Low Code Integration with Apache Camel.pdfLow Code Integration with Apache Camel.pdf
Low Code Integration with Apache Camel.pdf
 
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
 
Modern Java web applications with Spring Boot and Thymeleaf
Modern Java web applications with Spring Boot and ThymeleafModern Java web applications with Spring Boot and Thymeleaf
Modern Java web applications with Spring Boot and Thymeleaf
 
JSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked DataJSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked Data
 
Intro to Cypher
Intro to CypherIntro to Cypher
Intro to Cypher
 
React.js 세미나
React.js 세미나React.js 세미나
React.js 세미나
 
MySql Triggers Tutorial - The Webs Academy
MySql Triggers Tutorial - The Webs AcademyMySql Triggers Tutorial - The Webs Academy
MySql Triggers Tutorial - The Webs Academy
 
MongoDB
MongoDBMongoDB
MongoDB
 
9. index and index organized table
9. index and index organized table9. index and index organized table
9. index and index organized table
 
HTTP and Your Angry Dog
HTTP and Your Angry DogHTTP and Your Angry Dog
HTTP and Your Angry Dog
 
Angular
AngularAngular
Angular
 
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트) 마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
 
Back to Basics 1: Thinking in documents
Back to Basics 1: Thinking in documentsBack to Basics 1: Thinking in documents
Back to Basics 1: Thinking in documents
 
Migrating from RDBMS to MongoDB
Migrating from RDBMS to MongoDBMigrating from RDBMS to MongoDB
Migrating from RDBMS to MongoDB
 
Laravel introduction
Laravel introductionLaravel introduction
Laravel introduction
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...
jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...
jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...
 
Database Change Management as a Service
Database Change Management as a ServiceDatabase Change Management as a Service
Database Change Management as a Service
 

Viewers also liked

Bullying
BullyingBullying
Small business workshop 2012
Small business workshop 2012Small business workshop 2012
Small business workshop 2012
Carmen Velazquez
 
обработка текстовой информации
обработка текстовой информацииобработка текстовой информации
обработка текстовой информацииRuslan_krasav4eg
 
247958[1]
247958[1]247958[1]
247958[1]
f11pankajg
 
Dream Vacations Plus Income
Dream Vacations Plus IncomeDream Vacations Plus Income
Dream Vacations Plus Income
Carmen Velazquez
 
12205079‐pss7
12205079‐pss712205079‐pss7
12205079‐pss7
kyuenrandi
 
PERAWATAN RESTORATIF UNTUK MENCEGAH GAGAL-PULIH PADA LANJUT USIA DI MASYARAKAT
PERAWATAN RESTORATIF UNTUK MENCEGAH GAGAL-PULIH PADA LANJUT USIA  DI MASYARAKATPERAWATAN RESTORATIF UNTUK MENCEGAH GAGAL-PULIH PADA LANJUT USIA  DI MASYARAKAT
PERAWATAN RESTORATIF UNTUK MENCEGAH GAGAL-PULIH PADA LANJUT USIA DI MASYARAKAT
Bondan Palestin
 
Materi SMA - Gas Mulia
Materi SMA - Gas MuliaMateri SMA - Gas Mulia
Materi SMA - Gas Mulia
Rizki Amalia
 
Perawatan Usila dalam Keluarga
Perawatan Usila dalam KeluargaPerawatan Usila dalam Keluarga
Perawatan Usila dalam Keluarga
Bondan Palestin
 
Crestview family chiropractic ottawa customers reviews
Crestview family chiropractic ottawa customers reviews Crestview family chiropractic ottawa customers reviews
Crestview family chiropractic ottawa customers reviews Tesfay Haile
 
Evolucion de linux
Evolucion de linuxEvolucion de linux
Evolucion de linux
giovannyleonsanchez
 
Evolucion de linux
Evolucion de linuxEvolucion de linux
Evolucion de linux
giovannyleonsanchez
 
Askep Keluarga dengan Anorexia Nervosa
Askep Keluarga dengan Anorexia NervosaAskep Keluarga dengan Anorexia Nervosa
Askep Keluarga dengan Anorexia Nervosa
Bondan Palestin
 
06 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
06 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...06 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
06 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
Bondan Palestin
 
05 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
05 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...05 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
05 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
Bondan Palestin
 
02 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
02 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...02 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
02 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
Bondan Palestin
 
08 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
08 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...08 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
08 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
Bondan Palestin
 
09 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
09 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...09 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
09 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
Bondan Palestin
 
01 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
01 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...01 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
01 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
Bondan Palestin
 
PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL LANSIA DI...
PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL LANSIA DI...PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL LANSIA DI...
PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL LANSIA DI...
Bondan Palestin
 

Viewers also liked (20)

Bullying
BullyingBullying
Bullying
 
Small business workshop 2012
Small business workshop 2012Small business workshop 2012
Small business workshop 2012
 
обработка текстовой информации
обработка текстовой информацииобработка текстовой информации
обработка текстовой информации
 
247958[1]
247958[1]247958[1]
247958[1]
 
Dream Vacations Plus Income
Dream Vacations Plus IncomeDream Vacations Plus Income
Dream Vacations Plus Income
 
12205079‐pss7
12205079‐pss712205079‐pss7
12205079‐pss7
 
PERAWATAN RESTORATIF UNTUK MENCEGAH GAGAL-PULIH PADA LANJUT USIA DI MASYARAKAT
PERAWATAN RESTORATIF UNTUK MENCEGAH GAGAL-PULIH PADA LANJUT USIA  DI MASYARAKATPERAWATAN RESTORATIF UNTUK MENCEGAH GAGAL-PULIH PADA LANJUT USIA  DI MASYARAKAT
PERAWATAN RESTORATIF UNTUK MENCEGAH GAGAL-PULIH PADA LANJUT USIA DI MASYARAKAT
 
Materi SMA - Gas Mulia
Materi SMA - Gas MuliaMateri SMA - Gas Mulia
Materi SMA - Gas Mulia
 
Perawatan Usila dalam Keluarga
Perawatan Usila dalam KeluargaPerawatan Usila dalam Keluarga
Perawatan Usila dalam Keluarga
 
Crestview family chiropractic ottawa customers reviews
Crestview family chiropractic ottawa customers reviews Crestview family chiropractic ottawa customers reviews
Crestview family chiropractic ottawa customers reviews
 
Evolucion de linux
Evolucion de linuxEvolucion de linux
Evolucion de linux
 
Evolucion de linux
Evolucion de linuxEvolucion de linux
Evolucion de linux
 
Askep Keluarga dengan Anorexia Nervosa
Askep Keluarga dengan Anorexia NervosaAskep Keluarga dengan Anorexia Nervosa
Askep Keluarga dengan Anorexia Nervosa
 
06 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
06 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...06 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
06 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
 
05 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
05 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...05 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
05 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
 
02 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
02 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...02 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
02 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
 
08 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
08 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...08 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
08 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
 
09 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
09 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...09 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
09 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
 
01 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
01 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...01 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
01 TESIS PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL ...
 
PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL LANSIA DI...
PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL LANSIA DI...PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL LANSIA DI...
PENGARUH UMUR, DEPRESI DAN DEMENSIA TERHADAP DISABILITAS FUNGSIONAL LANSIA DI...
 

Similar to 스프링처럼 JDBC 리팩터링하기

MyBatis 개요와 Java+MyBatis+MySQL 예제
MyBatis 개요와 Java+MyBatis+MySQL 예제MyBatis 개요와 Java+MyBatis+MySQL 예제
MyBatis 개요와 Java+MyBatis+MySQL 예제
정완 전
 
Node.js and react
Node.js and reactNode.js and react
Node.js and react
HyungKuIm
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)
beom kyun choi
 
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
탑크리에듀(구로디지털단지역3번출구 2분거리)
 
데이터베이스패턴
데이터베이스패턴데이터베이스패턴
데이터베이스패턴Suan Lee
 
[Pgday.Seoul 2018] PostgreSQL 11 새 기능 소개
[Pgday.Seoul 2018]  PostgreSQL 11 새 기능 소개[Pgday.Seoul 2018]  PostgreSQL 11 새 기능 소개
[Pgday.Seoul 2018] PostgreSQL 11 새 기능 소개
PgDay.Seoul
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2
도현 김
 
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Jstl_GETCHA_HANJUNG
Jstl_GETCHA_HANJUNGJstl_GETCHA_HANJUNG
Jstl_GETCHA_HANJUNG
Jung Han
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
경원 이
 
스프링군살없이세팅하기(The way to setting the Spring framework for web.)
스프링군살없이세팅하기(The way to setting the Spring framework for web.)스프링군살없이세팅하기(The way to setting the Spring framework for web.)
스프링군살없이세팅하기(The way to setting the Spring framework for web.)
EunChul Shin
 
miss_pattern_v2
miss_pattern_v2miss_pattern_v2
miss_pattern_v2
YoungSu Son
 
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Young-Beom Rhee
 
overview of spring4
overview of spring4overview of spring4
overview of spring4
Arawn Park
 
Naver api for android
Naver api for androidNaver api for android
Naver api for androidSangon Lee
 
[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅
NAVER D2
 
5-4. html5 offline and storage
5-4. html5 offline and storage5-4. html5 offline and storage
5-4. html5 offline and storage
JinKyoungHeo
 
[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱
NAVER D2
 

Similar to 스프링처럼 JDBC 리팩터링하기 (20)

MyBatis 개요와 Java+MyBatis+MySQL 예제
MyBatis 개요와 Java+MyBatis+MySQL 예제MyBatis 개요와 Java+MyBatis+MySQL 예제
MyBatis 개요와 Java+MyBatis+MySQL 예제
 
Node.js and react
Node.js and reactNode.js and react
Node.js and react
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)
 
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
 
데이터베이스패턴
데이터베이스패턴데이터베이스패턴
데이터베이스패턴
 
Scala for play
Scala for playScala for play
Scala for play
 
[Pgday.Seoul 2018] PostgreSQL 11 새 기능 소개
[Pgday.Seoul 2018]  PostgreSQL 11 새 기능 소개[Pgday.Seoul 2018]  PostgreSQL 11 새 기능 소개
[Pgday.Seoul 2018] PostgreSQL 11 새 기능 소개
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2
 
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
 
Jstl_GETCHA_HANJUNG
Jstl_GETCHA_HANJUNGJstl_GETCHA_HANJUNG
Jstl_GETCHA_HANJUNG
 
Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기Jpa 잘 (하는 척) 하기
Jpa 잘 (하는 척) 하기
 
스프링군살없이세팅하기(The way to setting the Spring framework for web.)
스프링군살없이세팅하기(The way to setting the Spring framework for web.)스프링군살없이세팅하기(The way to setting the Spring framework for web.)
스프링군살없이세팅하기(The way to setting the Spring framework for web.)
 
miss_pattern_v2
miss_pattern_v2miss_pattern_v2
miss_pattern_v2
 
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
 
overview of spring4
overview of spring4overview of spring4
overview of spring4
 
Naver api for android
Naver api for androidNaver api for android
Naver api for android
 
[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅
 
5-4. html5 offline and storage
5-4. html5 offline and storage5-4. html5 offline and storage
5-4. html5 offline and storage
 
[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱
 
Html5 performance
Html5 performanceHtml5 performance
Html5 performance
 

스프링처럼 JDBC 리팩터링하기

  • 1. 한국 스프링 사용자 모임 (http://ksug.org) 1 Refactoring JDBC programming 2008.10.12 박찬욱
  • 2. 한국 스프링 사용자 모임 (http://ksug.org) 2 1. Hand-made JdbcTemplate 1.1 문제 인식 공유 1.2 해결 방안 모색 1.3 Refactoring with Strategy pattern 2. Spring JdbcTemplate 2.1 Best Practice of JDBC Strategy 2.2 Simplify JDBC operation Table of Contents
  • 3. 한국 스프링 사용자 모임 (http://ksug.org) 3 오늘의 목표는 ? • Composition + interface-based 프로그 래밍 기법  Spring JdbcTemplate 이해하기  어디 쓸 만한 곳이 없을까 ?
  • 4. 4한국 스프링 사용자 모임 (http://ksug.org) 1. Hand-made JdbcTemplate
  • 5. 한국 스프링 사용자 모임 (http://ksug.org) 5 1.1 문제 인식 공유 • 퀴즈 – iBatis – ORM(Hibernate or TopLink 등 ) – 내부 추상화 프레임웍 – 쌩 (pure) JDBC~?
  • 6. 한국 스프링 사용자 모임 (http://ksug.org) 6 1.1 문제 인식 공유 • JDBC 근본적인 문제 – TCFTC • Try-Catch-Finally-Try-Catch • 최고의 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...”); }catch(SQLException e){ // 예외 처리 ... }finally { if (stmt != null) { try { stmt.close(); } catch (SQLException ex) {} } if (con != null) try { con.close(); } catch (SQLException ex) { } }
  • 7. 한국 스프링 사용자 모임 (http://ksug.org) 7 1.1 문제 인식 공유 • 전혀 OO 스럽지 않은 반복적인 코드 (boilerplate code) 의 사용 으로 Data Access 코드가 드러워져 간다 “Bad Java code is bad J2EE code.” - Rod Johnson
  • 8. 한국 스프링 사용자 모임 (http://ksug.org) 8 1.2 해결 방안 모색 Strategy pattern 을 도입해서 문제 해결 시도
  • 9. 한국 스프링 사용자 모임 (http://ksug.org) 9 1.2 해결 방안 모색 • Strategy pattern 이란 ? – 실행 시점에 (at runtime) 알고리즘을 선택할 수 있는 방 법
  • 10. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 11 2.1 Best Practice of JDBC Strategy • Strategy pattern 참조 : wiki[2]
  • 12. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 17 1.3 Refactoring with Strategy pattern • Strategy pattern 이 적용된 Template.update()
  • 18. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 23 1.3 Refactoring with Strategy pattern • Strategy pattern 이 적용된 Template.query()
  • 24. 한국 스프링 사용자 모임 (http://ksug.org) 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( "select * from LECTURE", ... }, 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. 한국 스프링 사용자 모임 (http://ksug.org) 25 1.3 Refactoring with Strategy pattern 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; } }); get() 콜백 메소드로 구현 API 로 구분
  • 26. 한국 스프링 사용자 모임 (http://ksug.org) 26 1.3 Refactoring with Strategy pattern 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; } }); get()
  • 27. 한국 스프링 사용자 모임 (http://ksug.org) 27 1.3 Refactoring with Strategy pattern 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; } }); get()
  • 28. 한국 스프링 사용자 모임 (http://ksug.org) 28 1.3 Refactoring with Strategy pattern • Refactoring 2. – 여전히 Template 의 query() 와 update() 에서 JDBC API 가 중복되어 사용된다 !
  • 29. 한국 스프링 사용자 모임 (http://ksug.org) 29 1.3 Refactoring with Strategy pattern • Refactoring 2. 결과
  • 30. 한국 스프링 사용자 모임 (http://ksug.org) 30 1.3 Refactoring with Strategy pattern • 콜백 인터페이스가 적용된 공통 메소드
  • 31. 한국 스프링 사용자 모임 (http://ksug.org) 31 1.4 Summary • 구현한 템플릿 클래스와 인터페이스
  • 32. 한국 스프링 사용자 모임 (http://ksug.org) 32 1.4 Summary • JdbcTemplate 도입된 이후의 효과 – JDBC workflow 의 흐름 진행 주체 • DAO  JdbcTemplate – DAO 의 역할 충실화 • SQL, 파라미터 제공 or 결과 매핑 • 이 외의 다른 역할은 JdbcTemplate 를 비롯한 각 담당자에게 위임
  • 33. 한국 스프링 사용자 모임 (http://ksug.org) 33 2. SPRING JDBCTEMPLATE
  • 34. 한국 스프링 사용자 모임 (http://ksug.org) 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 "This is a special case of the Strategy design pattern. It appears different because the interface involved are so simple"
  • 35. 한국 스프링 사용자 모임 (http://ksug.org) 35 2.1 Best Practice of JDBC Strategy • JdbcTemplate with Strategy pattern DAO Template Callback Interface implementation 참조 : wiki[2]
  • 36. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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="lectureDao" class="org.springframework.lecture.jdbc.dao.JdbcLectureDao"> <property name="template" ref="dataSource" /> </bean> private JdbcTemplate template; public void setTemplate(JdbcTemplate template) { this.template = template; } <bean id="lectureDao" class="org.springframework.lecture.jdbc.dao.JdbcLectureDao"> <property name="template" ref="jdbcTemplate" /> </bean>
  • 42. 한국 스프링 사용자 모임 (http://ksug.org) 42 2.2 SIMPLIFY JDBC OPERATION
  • 43. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 44 2.2 Simplify JDBC operation • SimpleJdbc* 활용하기 – SimpleJdbcInsert • Simplify Insert behavior • JdbcTemplate + DatabaseMetaData • ‘fluid’ interface style
  • 45. 한국 스프링 사용자 모임 (http://ksug.org) 45 2.2 Simplify JDBC operation • SimpleJdbc* 활용하기 – SimpleJdbcCall • multi-threaded, reusable object representing a call to stored procedure or a stored function – SimpleJdbcTestUtils
  • 46. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 48 2.2 Simplify JDBC operation • SqlQuery – by Inheritance – Reusable, threadsafe class – Encapsulate SQL – MappingSqlQuery & UpdatableSqlQuery – Using meaningful method name
  • 49. 한국 스프링 사용자 모임 (http://ksug.org) 49 2.2 Simplify JDBC operation • RowCallbackHandler – Stateful – public void processRow(ResultSet rs) throws SQLException
  • 50. 한국 스프링 사용자 모임 (http://ksug.org) 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. 한국 스프링 사용자 모임 (http://ksug.org) 51 Reference • wiki[1]: http://en.wikipedia.org/wiki/Image:Strategy_Pattern_Diagram_ZP • wiki[2]: http://en.wikipedia.org/wiki/Image:Strategy_pattern_in_LePUS3.g • Tomas[1]: JDBC Development with the Spring Framework • Spring reference • Spring API • J2EE Design and Development • J2EE without EJB
  • 52. 한국 스프링 사용자 모임 (http://ksug.org) 52 감사합니다 .