[스프링] JDBC Template

June·2021년 7월 29일
1

JDBC

Java Database Connectivity

JDBC 순서
1) JDBC 드라이버 로드 (DBMS 별로 알맞은 드라이버 필요)
2) DB 연결
3) DB에 데이터를 읽거나 쓰기
4) DB 연결 종료

JDBC 코드 예제

public int addRole(Role role) {
	int insertCount = 0;
		
	try {
		Class.forName("com.mysql.jdbc.Driver");
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}
	
	String sql = "INSERT INTO role(role_id, description) VALUES (?, ?)";
		
	try (Connection conn = (Connection) DriverManager.getConnection(dburl, dbUser, dbpasswd);
		PreparedStatement ps = (PreparedStatement) conn.prepareStatement(sql)) {
			
		ps.setInt(1,  role.getRoleId());
		ps.setString(2,  role.getDescription());
			
		insertCount = ps.executeUpdate();
	} catch (Exception ex) {
		ex.printStackTrace();
	}
	return insertCount;
}

매번 드라이브를 로드하고, 커넥션을 맺고하는데 반복적인 코드가 너무 들어간다. 이런 공통적인 부분을 템플릿화하면 좋을 것 같다

  • 안정적이고 유연한 기술이지만, 로우 레벨 기술로 인식되고 있다.

  • 간단한 SQL을 실행하는 데도 중복된 코드가 반복적으로 사용되며, DB에 따라 일관성 없는 정보를 가진 채로 Checked Exception으로 처리한다.

Spring JDBC

DAO 패턴

  • 데이터 액세스 계층은 DAO 패턴을 적용하여 비지니스 로직과 데이터 액세스 로직을 분리하는 것이 원칙.

  • 비지니스 로직이 없거나 단순하면 DAO와 서비스 계층을 통합할 수도 있지만, 의미 있는 비지니스 로직을 가진 어플리케이션이라면 데이터 액세스 계층을 DAO 패턴으로 분리해야 함.

  • DAO 패턴은 서비스 계층에 영향을 주지 않고 데이터 액세스 기술을 변경할 수 있는 것이 장점.

커넥션 풀링을 지원하는 DataSource

커넥션 풀링은 미리 정해진 갯수만큼의 DB 커넥션을 풀에 준비해두고, 어플리케이션이 요청할 때마다 Pool에서 꺼내서 하나씩 할당해주고 다시 돌려받아서 Pool에 넣는 식의 기법.

  • 다중 사용자를 갖는 엔터프라이즈 시스템에서라면 반드시 DB 커넥션 풀링 기능을 지원하는 DataSource를 사용해야 함.

  • Spring에서는 DataSource를 공유 가능한 Spring Bean으로 등록해주어 사용할 수 있도록 해줌.

Spring JDBC란?

JDBC의 장점과 단순성을 그대로 유지하면서도 기존 JDBC의 단점을 극복할 수 있게 해주고, 간결한 형태의 API 사용법을 제공하며, JDBC API에서 지원되지 않는 편리한 기능을 제공.

  • Spring JDBC는 반복적으로 해야하는 많은 작업들을 대신 해줌.

  • Spring JDBC를 사용할 때는 실행할 SQL과 바인딩 할 파라미터를 넘겨주거나, 쿼리 실행 결과를 어떤 객체에 넘겨 받을지를 지정만 하면 된다.

  • Spring JDBC를 사용하려면 먼저, DB 커넥션을 가져오는 DataSource를 Bean으로 등록해야 한다.

Spring JDBC가 해주는 작업

Connection 열기와 닫기

  • Connection과 관련된 모든 작업을 Spring JDBC가 필요한 시점에서 알아서 진행.
  • 진행 중에 예외가 발생했을 때도 열린 모든 Connection 객체를 닫아줌.

Statement 준비와 닫기

  • SQL 정보가 담긴 Statement 또는 PreparedStatement를 생성하고 필요한 준비 작업을 해주는 것도 Spring JDBC가 한다.
  • Statement도 Connection과 마찬가지로 사용이 끝나고 나면 Spring JDBC가 알아서 객체를 닫아줌.

Statement 실행

  • SQL이 담긴 Statement를 실행하는 것도 Spring JDBC가 해줌.

  • Statement의 실행 결과는 다양한 형태로 가져올 수 있다.

ResultSet Loop처리

  • ResultSet에 담긴 쿼리 샐행 결과가 한 건 이상이면 ResultSet 루프를 만들어서 반복해주는 것도 Spring JDBC가 해주는 작업.

Exception 처리와 반환

  • JDBC 작업 중 발생하는 모든 예외는 Spring JDBC예외 변환기가 처리.

  • Checked Exception인 SQLException을 Runtime Exception인 DataAccessException 타입으로 변환.

Transaction 처리

  • Spring JDBC를 사용하면 transaction과 관련된 모든 작업에 대해서는 신경 쓰지 않아도 됨.

  • Transaction과 관련된 작업 : Commit, Rollback 등 작업의 단위

JDBC Template

Template 패턴이란?

  • 어떤 소스 코드상의 알고리즘에서 특정 환경 또는 상황에 맞게 확장 또는 변경을 해야 할 경우 매우 유용하게 사용하는 패턴

  • Template 패턴의 장점

    • 코드 중복 감소
    • 자식 클래스의 역할을 감소시키면서 핵심로직 관리 용이
    • 객체 추가 및 확장을 쉽게 가능
    • 재사용성 증가
  • Template 패턴의 단점

    • 추상 메소드가 너무 많으면 복잡성 증가
    • 추상 클래스와 구현 클래스간의 관계 복잡도가 증가

JDBC Template

Spring JDBC가 제공하는 클래스 중 JdbcTemplate은 JDBC의 모든 기능을 최대한 활용할 수 있는 유연성을 제공하는 클래스이다.

  • JdbcTemplate이 제공하는 기능은 실행, 조회, 배치의 세가지 작업.
  • 실행 : Insert나 Update같이 DB의 데이터에 변경이 일어나는 쿼리를 수행하는 작업
  • 조회 : Select를 이용해 데이터를 조회하는 작업
  • 배치 : 여러 개의 쿼리를 한 번에 수행해야 하는 작업
  • 스프링의 가장 기본적인 Data Access 템플릿으로 쿼리 기반으로 데이터 베이스의 접근 가능

  • 모든 영속성 프래임워크는 내부적으로 JDBC API를 이용

  • DAO 계층에서 Jdbc Template API를 사용

  • Data Source

    • DB Server와 연결 시키는 연결 팩토리
    • JDBC의 일부분
    • Connection 의 정보를 가지고 있고 Bean 으로 등록하여 인자를 넘겨준다.
    • DB Connection Pooling 기능을 가지고 있음
    • 기본적으로 BasicDataSource를 사용
  • JDBC Template 같은경우 제네릭을 사용해 어떠한 값이 오든 그대로 반환

  • 번외 (영속성 프레임워크 종류)

    • SQL Mapper : Mybatis, Ibatis, JDBC Template
    • ORM : JPA, Hibernate

JDBC Template 사용 예시

JdbcTemplate 클래스 생성

  • JdbcTemplate은 DateSource를 파라미터로 받아서 아래와 같이 생성할 수 있다.
JdbcTemplate template = new JdbcTemplate(dateSource);
  • DateSource는 보통 Bean으로 등록해서 사용하므로 JdbcTemplate이 필요한 DAO 클래스에서 DateSource Bean을 DI 받아서 JdbcTemplate을 생성할 때 인자로 넘겨주면 됨.

  • JdbcTemplate은 멀티스레드 환경에서도 안전하게 공유해서 쓸 수 있기 때문에 DAO 클래스의 인스턴스 변수에 저장해두고 사용할 수 있다.

JdbcTemplate 클래스의 update() 메서드

  • INSERT, UPDATE, DELETE와 같은 SQL을 실행할 때는 JdbcTemplate의 update() 메서드를 사용.
int update (String sql, [SQL 파라미터])
  • update() 메서드를 호출할 때는 SQL과 함께 바인딩 할 파라미터는 Object 타입 가변인자 (Object ... args)를 사용할 수 있다.

  • update() 메서드의 리턴되는 값은 SQL 실행으로 영향을 받은 레코드의 개수를 리턴.

JdbcTemplate 클래스의 queryForObject() 메서드

  • SELECT SQL을 실행하여 하나의 Row를 가져올 때는 JdbcTemplate의 queryForObject() 메서드를 사용
<T> T queryForObject (String sql, [SQL 파라미터], RowMapper<T> rm)
  • SQL 실행 결과는 여러 개의 Column을 가진 하나의 Row

  • T는 VO 객체의 타입에 해당.

  • SQL 실행 결과로 돌아온 여러개의 Column을 가진 한 개의 Row를 RowMapper 콜백을 이용해 VO 객체로 매핍.

JdbcTemplate 클래스의 query() 메서드

  • SELECT SQL을 실행하여 여러 개의 Row를 가져올 때는 JdbcTemplate의 query() 메서드를 사용
<T> List<T> query (String sql, [SQL 파라미터], RowMapper<T> rm)
  • SQL 실행 결과로 돌아온 여러 개의 Column을 가진 여러개의 Row를 RowMapper 콜백을 이용해 VO 객체로 매핑.

  • 결과 값은 매핑한 VO 객체를 포함하고 있는 List 형태로 받는다. List의 각 요소가 하나의 Row에 해당

  • 스프링 JdbcTemplate과 MyBatis 같은 라이브러리는 JDBC API에서 본 반복 코드를 대부분 제거해준다. 하지만 SQL은 직접 작생해야 한다. 그래
  • JPA는 기존의 반복 코드는 물론이고, 기본적인 SQL도 JPA가 직접 만들어서 실행해준다.
  • JPA를 사용하면, SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환을 할 수 있다.
  • JPA를 사용하면 개발 생산성을 크게 높일 수 있다.

0개의 댓글