데이터 액세스 공통 개념
DAO(Data Access Object) 패턴
- 데이터 액세스 계층은 DAO 패턴을 적용하여 비즈니스 로직과 데이터 액세스 로직을 분리하는 것이 원칙이다.
- 비즈니스 로직이 없거나 단순하면 DAO와 서비스 계층을 통합 할 수 있지만 의미 있는 비즈니스 로직을 가진 엔터프라이즈 애플리케이션이라면 데이터 액세스 계층을 DAO 패턴으로 분리해야 한다.
- DAO패턴은 서비스 계층에 영향을 주지 않고 데이터 액세스 기술을 변경할 수 있는 장점을 가지고 있다.
커넥션 풀링을 지원하는 DataSource
- 커넥션 풀링은 미리 정해진 개수만큼의 디비 커넥션 풀에 준비해두고, 애플리케이션이 요청할 때 마다 풀에서 꺼내서 하나씩 할당해주고 다시 돌려받아 풀에 넣는식의 기법이다.
- 다중 사용자를 갖는 엔터프라이즈 시스템에서라면 반드시 디비 커넥션 풀링 기능을 지원하는 Datasource 기능을 사용해야 한다.
- Spring 에서는 Datasource를 공유 가능한 Spring Bean으로 등록해 주어 사용할 수 있도록 해준다.
DataSource 구현 클래스 종류
- 테스트환경을 위한 DataSource
SimpleDriverDataSource
- 스프링이 제공하는 가장 단순한 형태의 DataSource 구현 클래스이다.
- getConnection()을 호출할 때마다 매번 DB 커넥션을 새로 만들고 따로 풀 관리를 하지 않으므로 단순 테스트 용도로만 사용하자
SingleConnectionDriverDataSource
- 순차적으로 진행되는 통합 테스트에서는 사용 가능하다.
- 매번 DB 커넥션을 생성하지 않기 때문에 Simple~ 보다 빠르게 동작한다.
DataSource 종류
- 오픈소스 DataSource
Apache Commons DBCP
- 가장 유명한 오픈소스 DB 커넥션 풀 라이브러리 이다.
c3p0 JDBC/DataSource Resource Pool
- c3p0는 JDBC 3.0 스펙을 준수하는 Connection과 Statement Pull을 제공하는 라이브러리이다.
두가지 모두 수정자(setter) 메서드를 제공하므로 Spring Bean으로 등록해서 사용하기 편하다.
Spring JDBC의 개요
JDBC란?
- 모든 자바의 데이터 액세스 기술의 근간이 된다.
- 엔티티클래스와 애노테이션을 이용하는 최신 ORM 기술도 내부적으로는 DB와의 연동을 위해 JDBC를 이용한다.
- 안정적이고 유연한 기술이지만 , 로우레벨 기술로 인식되고 있다.
- 간단한 SQL을 실행하는데도 중복코드가 반복적으로 사용되며 DB에 따라 일관성없는 정보를 가진 채료 checked Exception 으로 처리한다.
- 장점 - 대부분 개발자가 잘 알고 있는 친숙한 데이터 액세스 기술로 별도의 학습없이 개발 가능
- 단점 - Connection 같은 공유 리소스를 제대로 릴리즈 해주지 않으면 시스템 자원이 바닥나는 버그를 발생
Spring JDBC란?
- jdbc의 장점과 단순성을 그대로 유지하면서 기존 jdbc의 단점을 극복할 수 있게 해주고 간결한 형태의 api 사용법을 제공하며, jdbc 에서 지원되지 않는 편리한 기능을 제공
- 반복적으로 해야할 많은 작업들을 대신 해준다.
- 실행할 SQL과 바인딩할 파라미터를 넘겨주거나, 쿼리의 실행결과를 어떤 객체에 넘겨받을지 지정하는 것만 하면 됨
- 사용하려면 먼저, DB 커넥션을 가져오는 DataSource 를 빈으로 등록해야 한다.
Spring JDBC가 해주는 작업
Connection 열기 / 닫기
- 커넥션과 관련된 모든 작업을 Spring JDBC가 필요한 시점에서 알아서 진행
- 진행 중 예외가 발생했을 때에도 열린 모든 커넥션 객체를 닫아준다.
Statement 준비와 닫기
- SQL 정보가 담긴 Statement 또는 PreparedStatement를 생성하고 필요한 준비 작업을 해줌
- Statement 도 커넥션과 마찬가지로 사용이 끝나고 나면 Spring JDBC가 알아서 객체를 닫아줌
Statement 실행
- SQL이 담긴 Statement 를 실행
- Statement의 실행결과는 다양한 형태로 가져올 수 있다.
ResultSet Loop 처리
- ResultSet에 담긴 쿼리 실행 결 과가 한 건 이상이면 ResultSet 루프를 만들어 반복해줌
Exception 처리와 반환
- JDBC 작업 중 발생하는 모든 예외는 Spring JDBC 예외 변환기가 처리
- 체크 예외 Checked Exception 인 SQL Exception을 런타임 예외 인 DataAccessException 타입으로 변환
- try , catch 문을 쓸 필요 없다.
Transaction 처리
- transaction과 관련된 모든 작업에 대해서는 신경 쓰지 않아도 된다. commit / rollback
Spring JDBC 의 jdbcTemplate 클래스
jdbcTemplate 클래스
- Spring JDBC가 제공하는 클래스 중 jdbcTemplate는 JDBC 의 모든 기능을 최대한 활용할 수 있는 유연성을 제공하는 클래스이다.
- jdbcTemplate이 제공하는 기능은 실행, 조회, 배치의 세 가지 작업이다.
- 실행 : insert나 Update 같이 DB의 데이터에 변경이 일어나는 쿼리를 수행하는 작업
- 조회 : Select 를 이용해 데이터를 조회하는 작업
- 배치 : 여러 개의 쿼리를 한 번에 수행해야 하는 작업
jdbcTemplate 클래스 생성
- jdbcTemplate 는 DataSource를 파라미터로 받아 아래와 같이 생성 가능하다.
jdbcTemplate template = new jdbcTemplate(dataSource);
- DataSource는 보통 Bean으로 등록해서 사용하므로 jdbcTemplate 이 필요한 DAO 클래스에서 DataSource Bean을 DI 받아 jdbcTemplate를 생성할 때 인자로 넘겨주면 된다.
- jdbcTemplate는 멀티스레드 환경에서도 안전하게 공유해서 쓸 수 있기 때문에 DAO 클래스의 인스턴스 변수에 저장해두고 사용할 수 있다.
jdbcTemplate 클래스 생성 코드
- 아래의 코드는 일반적으로 사용되는 DAO 클래스의 기본구조이다. Datasource에 대한 수정자 메서드에서 직접 jdbcTemplate 객체를 생성해준다.
public class UserDAIjdbc {
jdbcTemplate jdbctemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new jdbcTemplate(dateSource);
}
}
jdbcTemplate 클래스의 update() 메서드
- insert, update, delete 와 같은 SQL을 실행할 때는 jdbcTemplate의 update() 메서드를 사용한다.
int update(String sql, [SQL파라미터])
- update() 메서드를 호출할 때 SQL과 함께 바인딩 할 파라미터는 Object 타입의 가변인자 (Object .. args)를 사용할 수 있다.
- update() 메서드의 리턴되는 값은 SQL 실행으로 영향을 받은 레코드의 개수를 리턴한다.
jdbcTemplate 클래스의 update() 메서드 코드
public int update(User user) {
StrinfBuffer updateQuery = new StringBuffer();
updateQuery.append("UPDATE USERS SET ");
updateQuery.append("password=?, name=? ");
updateQuery.append("WHERE id=? ");
int result = this.jdbcTemplate.update(updateQuery.toString(),
user.getName(), user.getPassword(), user.getId() );
return result;
}
jdbcTemplate 클래스의 queryForObject() 메서드 - 여러개의 컬럼 / 한개의 로우
- SELECT SQL을 실행하여 하나의 ROW를 가져올 때는 jdbcTemplate 의 queryForObject() 메서드를 사용
<T> T quertForObject(String sql, [SQL 파라미터], RowMapper<T> rm)
- SQL 실행결과는 여러개의 컬럼을 가진 하나의 로우
- T는 VO의 객체 타입
- SQL 실행결과로 돌아온 여러개의 컬럼을 가진 한개의 로우를 RowMapper 콜백을 이용해 VO 객체로 매핑
jdbcTemplate 클래스의 queryForObject() 메서드 코드
public User findUser (String id) {
return this.jdbcTemplate.queryForObject("select * from users
where id=?", new Object[] {id},
new RowNMapper<User>() {
public User mapRow(ResultSet rs, int rowNum)
throws SQLException{
User user = new User();
user.setId(rs.getString("id"));
user.setName(re.getString("name"));
user.setPassword(rs.getString("password"));
retrun user;
}
}//RowMapper
}//queryForObject
}//findUser
jdbcTemplate 클래스의 query() 메서드 - 여러개의 컬럼 / 여러개의 로우
- SELECT SQL을 실행하여 여러 개의 로우를 가져올 때는 jdbcTemplate의 query() 메서드를 사용한다.
<T> List<T> query(String sql, [SQL 파라미터], RowMapper<T> rm)
- Sql 실행 결과로 돌아온 여러개 개의 컬럼을 가진 여러 개의 로우를 RowMapper 콜백을 이용해 VO 객체로 매핑해준다.
- 결과 값은 매핑 한 VO 객체를 포함하고 있는 리스트 형태로 받는다. 리스트의 각 요소가 하나의 ROW에 해당 된다.
'Back-end > Spring' 카테고리의 다른 글
AOP 개요 (0) | 2021.06.11 |
---|---|
Spring JDBC 환경설정 (0) | 2021.06.11 |
사용자 관리 프로젝트 (0) | 2021.06.10 |
DI 애플리케이션 작성(4) (0) | 2021.06.10 |
DI 애플리케이션 작성(3) (0) | 2021.06.10 |