[Spring Study] - DB Link :: 상세 보충 필요

uHan2·2021년 1월 23일
0

TIL.BackEnd

목록 보기
8/12
post-custom-banner

비록 시작은 코딩일기지만, 그 끝은 창대하게
어엿한 개발자 블로그로 성장할 수 있도록.


Spring Study

본 게시글은
Endless Creation Spring Study
에 사용하는 자료입니다.


Spring

Spring 에서 제공하는 JDBC Template 이전에 Java 에서는 데이터베이스와 연동할 수 있는 JDBC 라는 것이 이미 존재한다. JDBC 의 전체적인 흐름은 다음 그림과 같다.

각 단계별 흐름을 간단히 짚어보자.

  • 1 단계 :: JDBC 드라이버 로드

이름대로 JDBC 의 드라이버를 로드하는 단계이다.

데이터베이스에 접속하려면 먼저 해당 데이터베이스의 JDBC 드라이버를 로드해야 한다.

일반적으로 Class.forName() 메서드를 이용하여 JDBC 드라이버를 직접 프로그램 코드에서 로드한다.

데이터베이스마다 구현한 클래스 이름이 다름으로 다른 데이터베이스를 사용한 경우 해당 클래스 이름을 사전에 알아 두어야 한다.

 Class.forName("com.mysql.jdbc.Driver");
  • 2 단계 :: 데이터베이스 연결

다루고 싶은 데이터베이스와 연결 하는 부분이다.

JDBC URL ::
JDBC URL은 데이터베이스에 대한 다양한 정보를 포함한다. JDBC URL 구조는 다음과 같다.

jdbc:<하위 프로토콜>:<데이터 원본 식별자>

각 데이터베이스별로 JDBC URL이 다르다.

Connection 클래스 인스턴스 레퍼런스 얻기 ::
DriverManagergetConnection 메서드를 이용

Connection conn = DriverManger.getConnetion(JDBC_URL, “아이디”, “비밀번호”)
  • 3 단계 :: Statement 생성

Statement는 데이터베이스 연결로부터 SQl문을 수행할 수 있도록 하는 클래스로, 대표적으로 다음과 같은 메서드가 사용된다.

executeQuery() ::
SELECT문을 수행할 때 사용. 반환 값은 ResultSet 클래스의 인스턴스로, 해당 SELECT문의 결과에 해당하는 데이터에 접근하는 방법을 제공한다.

executeUpdate() ::
UPDATE, DELETE와 같은 문을 수행할 때 사용. 반환 값은 int 값으로, 처리된 데이터의 수를 반환한다.

Statement stmt = conn.createStatement();
Stmt.executeQuery(“select name from member”);

PreparedStatement ::
Sql문을 미리 만들어두고 변수를 따로 입력하는 방식이며, Statement 클래스를 상속받기 때문에 Statement 클래스 메서드를 모두 사용할 수 있다.

PreparedStatement pstmt = conn.prepareStatement(“insert into test value(?,?));
pstmt.setString(1, request.getParameter(“username”);
pstmt.setString(2, request.getParameter(“email”);
pstmt.executeUpdate();

Statement의 종료 ::
다른 JDBC 리소스와 마찬가지로 Statement 역시 사용하지 않을 때에는 닫아주어야 한다.

stmt.close()
pstmt.close()
  • 4 단계 :: SQL문 전송

Statement 나 PreparedStatement의 executeUpdate(), executeQuery() 메서드를 사용하면 된다.

Int count = pstmt.executeUpdate();
  • 5 단계 :: 결과 받기

executeQuery()를 사용한 경우 결과 데이터를 처리하기 위한 ResultSet 객체가 필요하다.

ResultSet rs = pstmt.executeQuery();

ResultSet은 조회한 결과 값에 순차적으로 접근할 수 있다. ResultSet은 실제 처리 결과의 데이터가 모두 있는 구조가 아니라, 데이터의 인덱스 정보만 있는 구조이다. 따라서 ResultSet만 가져오고 연결을 끊으면 안되며, 필요한 데이터를 모두 가져온 이후, ResultSet을 close()하고, 그 다음 connection을 close()해야 한다.

ResultSet rs = pstmt.executeQuery();
While(rs.next()){
	name = rs.getString(1); // or rs.getString(“name”);
	age = rs.getInt(2); // or rs.getString(“age”);
}

ResultSet은 next() 메서드를 이용해서 다음 로우로 이동할 수 있다.
로우에서 각각의 칼럼 값을 가져오려면 rs.getXxx() 메서드를 이용한다.
getXxx()에서 칼럼을 지정하는 방법으로는 해당 칼럼의 index값이나 칼럼 이름을 사용한다.
가급적 index보다 칼럼 이름을 사용하는 것을 권장한다.( 코드 이해를 돕고, 유지 보수에도 편리)

  • 6 단계 :: 연결 해제

데이터베이스와 연결을 관리하는 Connection 인스턴스는 사용한 뒤 반납하지 않으면 계속해서 연결을 유지하게 되며, 자원의 낭비된다.
사용자가 많은 시스템일 수록 커넥션 관리가 중요하다.

conn.close();

이렇게 JDBC 의 전반적인 흐름을 살펴보았다.
하지만 JDBC 를 그냥 사용하기에는 데이터 처리와는 상관없는 코드가 반복되는 문제가 있다. 실제핵심은 우리가 Statement 를 날려 Query 를 실행하고 데이터를 처리하는 부분이다. 이런 반복되는 문제를 해결하는 방법에는 템플리 메서드 패턴전략 패턴이 있는데 Spring 에서 이 두 패턴을 엮은 JdbcTemplate Class 를 제공해준다.


Spring JDBC TemplateJDBC 에서 DriveManager 가 하는 일들을 JdbcTemplate 에게 맡긴다. 따라서, 개발자는 쿼리문으로 질의할 수 있다. 이 때, JdbcTemplateSQL Mapper 중 하나이다.

또 다른 장점으로는 Transaction 관리가 용이하다는 점이다. 그냥 JDBC 를 이용할 때에는 commit()rollback() 을 이용해 Transaction 을 일일이 관리해주어야 한다. 하지만 Transactional Annotation(@Transactional) 을 통해 손쉽게 Transaction 을 관리할 수 있다.


앞서 Spring 의 장점으로 소개 했듯이 Spring 에서는 Transaction 처리를 지원하는데 그 중 Annotaion 방식으로 @Transactional 을 선언하는 방법이 일반적이며, 선언적 트랜잭션이라 부른다.

클래스, 메서드 위에 @Transactional 이 추가되면, 이 클래스에 Transaction 기능이 적용된 Proxy 객체가 생성된다. 이 Proxy 객는 @Transactional 이 포함된 메소드가 호출될 경우, PlatformTransactionManager 을 사용하여 Transaction을 시작하고, 정상 여부에 따라 Commit 또는 Rollback 한다.

해당 Annotaion 을 적용하면 적용된 클래스 또는 메소드에 Transaction 이 적용된다. 따라서 로직 흐름에 맞추어 전체적으로 Transaction 을 적용할 것인지, 아니면 특정 메소드에 적용할 것인지 전략을 잘 세워야 한다.

profile
For the 1% inspiration.
post-custom-banner

0개의 댓글