Spring

Spring_chapter04_스프링 JDBC

강용민 2022. 3. 28. 16:38

1.데이터 액세스 층

데이터 액세스 층의 역할은 데이터 액세스 처리를 비즈니스 로직 층에서 분리하는 것이다.

이를 통해 비즈니스로직층은 데이터 액세스처리에 신경쓰지 않고 기술할 수 있으므로 소스코드가 간결해지며, 유지관리가 쉬워진다.

 

DAO(Data Access Object)

DAO는 데이터 액세스 처리에 특화된 오브젝트로 데이터 취득과 변경(CRUD)에 데이터 처리의 역할을 한다.

DAO가 CRUD메서드를 실행하면 자 JDBC,Hybernate,MyBatis, JPA등의 여러 프레임워크를 통해 데이터 액세스 기술을 처리한다.

 

DAO패턴

DAO패턴은 데이터 취득과 변경에 데이터 처리를 DAO 오브젝트로 분리하는 패턴이다.

구성은 DAO 인터페이스와 DAO 인터페이스를 구현한 클래스, 데이터 전송 객체(Data Transform Object)로 나눠져있다.

그럼 Spring은 데이터 액세스 기술을 쉽게 사용하기 위한 기능을 제공한다.

데이터 액세스 기술을 처리하는 자바 기술에는 여러가지가 존재하는데, JDBC, Hybernate, Mybatis, JPA등이 있다.

 

Data Source

데이터 소스는 데이터 액세스 기술 종류와 상관없이 데이터베이스 접속을 관리해주는 인터페이스이다.

DB와 관계된 커넥션 정보를 담고있으며, 빈으로 등록하여 인자로 넘겨주는데, 이 과정을 통해 Spring은 데이터 소스로 DB와 연결을 획득한다.

Data Source를 구현하기 위해선 Apache Commons DBCP를 POM.XML의 dependency에 추가하고,

Bean 정의파일(applicationContext.xml)에 DBCP 데이터 소스를 설정한다.

 

DB Connection Pool

자바 프로그램에서 데이터베이스 연결(커넥션 객체를 얻는것)은 오래걸리기에,

일정량의 Connection객체를 미리 만들어 저장해두었다가 요청 시 꺼낸다.

이로인해 속도와 퍼포먼스가 좋아지며, 커넥션풀을 관리하고, 커넥션객체를 풀에서 꺼냈다 반납하는 이러한 과정을 DataSource가 한다.

 

2.스프링 JDBC

JDBC 이용의 문제점은 다음과 같다.

  • 대량의 소스 코드를 기술
  • 다양한 에러 원인을 파악하기 위한 코딩이 필요
  • 데이터베이스 제품마다 에러 코드가 달라서 코드의 일관성 유지가 어려움

이러한 문제들을 스프링 JDBC는 다음과 같이 해결했다.

  • JDBC를 래핑한 API를 제공해 소스 코드를 단순화
  • JDBC를 직접 사용할 때 발생하는 장황한 코드를 은닉
    • 커넥션 연결 종료
    • SQL문의 실행
    • SQL 문 실행 결과 행에 대한 반복 처리
    • 예외 처리

스프링 JDBC가 제공하는 중요 탬플릿은 JdbcTemplate, NamedParameterTemplate가 있다.

JdbcTemplate 클래스가 제공하는 메서드는 다음과 같다.

메서드 명 설명
queryForObject 하나의 결과 레코드 중에서 하나의 컬럼 값을 가져올 때 사용한다.
RowMapper와 함께 사용하면 하나의 레코드 정보를 객체에 매핑한다.
queryForMap 하나의 결과 레코드 정보를 Map 형태로 매핑할 수 있다.
queryForList 여러 개의 Map 형태의 결과 레코드를 다룰 수 있다.
query 여러 개의 레코드를 객체로 변환하여 처리한다.
update 데이터의 변경(INSERT, UPDATE, DELETE)을 실행할 때 사용한다.

 

SELECT문

취득 결과가 레코드 건수 또는 특정 컬럼만 취득하고 싶을 경우 사용한다.

 

queryForObject 메서드 사용예제

  • 제 1인수 : SQL 문자열
  • 제 2인수 : 반환형 클래스 호브젝트(int)
JdbcTemplate jdbcTemplate = cvx.getBean(JdbcTemplate.class);
int count = jdbcTemplate.queryForObject(
	"SELECT COUNT(*) FROM STUDENT", Integer.class);
  • 제 1인수 : SQL 문자열
  • 제 2인수 : 반환형 클래스 오브젝트(String)
  • 제 3인수 : 파라미터 값
String name = jdbcTemplate.queryForObject(
	"SELECT username FROM STUDENT WHERE id=?",string.class, id);

queryForMap 메서드 사용예제

한 레코드 값을 Map(컬럼 이름을 키로 값을 저장) 데이터로 변환

Map<String, Object> student = jdbcTemplate.queryForMap(
	"SELECT * FROM STUDENT WHERE id=?",id);
String name = (String)Student.get("username");

queryForList 메서드 사용예제

여러 레코드 값을 Map 데이터로 변환

List<Map<String, Object>> studentList = jdbcTemplate.queryForMap(
	"SELECT * FROM STUDENT");

도메인으로 변환할 경우

queryForObject 메서드와 query 메서드를 이용한다.

public StudentVO read(String id) throws Exception{
	StudentVO vo = null;
    try{
    	vo = jdbcTemplate.queryForObject(
        	"SELECT * FROM STUDENT WHERE ID=?"
            //BeanPropertyRowMapper를 사용할 경우
            //StudentVO의 프로퍼티 명과 테이블 컬럼 명이 같아야 한다.
            //그렇지 않을 경우는 RowMapper 인터페이스를 구현해서 StudentVO로 변환 처리 필요
            ,new BeanPropertyRowMapper<StudentVO>(StudentVO.class),id);
    }
    catch(EmptyResultDataAccessException e){
   	  return vo;
    }
    return vo;
 }