Everything has an expiration date
[inflearn] 20240121 [스프링-프레임워크] - 24강 필기 본문
[inflearn] 20240121 [스프링-프레임워크] - 24강 필기
Jelly-fish 2024. 1. 21. 23:0424강 - JdbcTemplate
Java 언어를 사용해서 Database 와 통신하기 위한 방법에 대해서 살펴본다.
24-1 JDBC의 단점을 보완한 JdbcTemplate
24-2 DataSource 클래스
24-1 JDBC의 단점을 보완한 JdbcTemplate
【 JDBC 】
① 드라이버 로딩
② DB 연결
③ SQL 작성 및 전송
④ 자원 해제
【 JdbcTemplate 】
① JdbcTemplate
▶ (드라이버 로딩, DB 연결, 자원해제)
② SQL 작성 및 전송
→ Spring 에서는 동일한 작업 (드라이버 로딩, DB 연결, 자원해제)이 반복되는 것을 막기 위해서
Jdbc Template 을 제공하고 있다.
24-2 DataSource 클래스
◎ DriverManagerDataSource
- 데이터베이스 연결과 관련된 정보(데이터베이스 경로, Url, 유저 ID, PW) 를 갖고 있는 객체.
- `DataSource` 는 Spring 또는 c3p0에 제공하는 클래스를 이용할 수 있다.
Spring
▶ `org.springframework.jdbc.datasource.DriverManagerDataSource`
c3p0
▶ `com.mchange.v2.c3p0.DriverManagerDataSource`
JdbcTemplate 사용을 위한 과정
1. pom.xml 수정 - 의존 설정
pom.xml
<repositories>
<repository>
<id>oracle</id>
<name>ORACLE JDBC Repository</name>
<url>http://maven.jahia.org/maven2</url>
</repository>
</repositories>
<!-- Spring JDBC 등록 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!-- c3p0 모듈 등록 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5</version>
</dependency>
→ `oracle repository`를 추가했기 때문에 Spring JDBC, c3p0 의존 설정이 가능한 것이다.
2-1. DAO 클래스 수정
① `c3p0`의 `DriverManagerdataSource`를 사용했을 경우.
① MemberDao.java
package com.bs.lec23.member.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import com.bs.lec23.member.Member;
import com.mchange.v2.c3p0.DriverManagerDataSource; //-- ①
@Repository
public class MemberDao implements IMemberDao
{
private String driver = "oracle.jdbc.driver.OracleDriver";
private String url = "jdbc:oracle:thin:@localhost:1521:xe";
private String userid = "scott";
private String userpw = "tiger";
// ① c3p0 의 DriverManagerDataSource 를 사용.
private DriverManagerDataSource dataSource;
private JdbcTemplate template;
/*
private Connection conn = null;
prvate PreparedStatement pstmt = null;
private ResultSet rs = null;
*/
public MemberDao()
{
// dataSource 를 이용해서
// Dao 객체가 생성될 때 딱 한 번만 설정을 하고 넘어갈 수 있도록 한다.
dataSource = new DriverManagerDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(userid);
dataSource.setPassword(userpw);
}
....
}
② `SpringJDBC`의 `DriverManagerdataSource`를 사용했을 경우.
② MemberDao.java
package com.bs.lec23.member.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import com.bs.lec23.member.Member;
@Repository
public class MemberDao implements IMemberDao
{
private String driver = "oracle.jdbc.driver.OracleDriver";
private String url = "jdbc:oracle:thin:@localhost:1521:xe";
private String userid = "scott";
private String userpw = "tiger";
//-- ②
org.springframework.jdbc.datasource.DriverManagerDataSource dataSource;
private JdbcTemplate template;
public MemberDao()
{
// dataSource 를 이용해서
// Dao 객체가 생성될 때 딱 한 번만 설정을 하고 넘어갈 수 있도록 한다.
dataSource = new org.springframework.jdbc.datasource.DriverManagerdataSource();
dataSource.setDeiverClassName(driver);
dataSource.setUrl(url);
dataSource.setUserName(userid);
dataSource.setPassword(userpw);
}
....
}
DriverManagerDataSource - 메소드명 차이점 표 정리
→ DriverManagerDataSource 를 어떤 클래스(`c3p0`, `SpringJDBC`)에서 사용했느냐에 따라
메소드명에 차이가 존재한다.
구분 | c3p0 | Spring JDBC |
드라이버 로딩 | setDriverClass(driver) | setDriverClassName(driver); |
DB 연결 | setJdbcUrl(url) | setUrl(url) |
유저 ID | setUser(userid) | setUserName(userid) |
유저 PW | setPassword(userpw) | setPassword(userpw) |
2-2. DAO 클래스 수정 - `c3p0` DriverManagerDataSource 사용.
MemberDao.java
package com.bs.lec23.member.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import com.bs.lec23.member.Member;
import com.mchange.v2.c3p0.DriverManagerDataSource; //-- ①
@Repository
public class MemberDao implements IMemberDao
{
private String driver = "oracle.jdbc.driver.OracleDriver";
private String url = "jdbc:oracle:thin:@localhost:1521:xe";
private String userid = "scott";
private String userpw = "tiger";
// ① c3p0 의 DriverManagerDataSource 를 사용.
private DriverManagerDataSource dataSource;
private JdbcTemplate template;
public MemberDao()
{
// dataSource 를 이용해서
// Dao 객체가 생성될 때 딱 한 번만 설정을 하고 넘어갈 수 있도록 한다.
dataSource = new DriverManagerDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(userid);
dataSource.setPassword(userpw);
template = new JdbcTemplate();
template.setDatasource(dataSource);
}
}
Ⅲ. JDBC Template 적용 완료!
① 데이터베이스와 관련된 정보를 `dataSource` 라는 객체에 모두 set 하여 담아준다.
dataSource = new DriverManagerDataSource(); dataSource.setDriverClass(driver); dataSource.setJdbcUrl(url); dataSource.setUser(userid); dataSource.setPassword(userpw);
② 이후, 그것을 더 이상 반복해서 작업하지 않도록 `JdbcTemplate`에 다시 set 을 해 주는 것이다.
template = new JdbcTemplate(); template.setDatasource(dataSource);
이렇게 처리하게 되면, 더 이상 우리는 DAO 의 메소드를 정의할 때마다
① 드라이버 로딩, ② DB 연결, ④ 자원 해제 의 과정을 반복하지 않아도 된다!
Ⅳ. JdbcTemplate 를 적용한 후, MemberDAO 의 메소드 수정하기
① `int memberInsert(Member member)` 메소드 수정.
@Override
public int memberInsert(Member member)
{
int result = 0;
String sql = "INSERT INTO MEMBER (MEMID, MEMPW, MEMMAIL)"
+ " VALUES (?, ?, ?)";
result = template.update(sql, member.getMemId(), member.getMemPw(), member.getMemMail());
return result;
}
→ 코드가 굉장히 간결해 진 것을 확인할 수 있다!
★ [Check!!!]
result = template.update(sql, member.getMemId(), member.getMemPw(), member.getMemMail());
===== ===========================================================
① ②
[쿼리문] [PrepareStatement 로 set 해 주어야하는 ? 에 들어가야 할 값.]
▶ `PrepareStatement` 로 `pstmt.setXxx(index, value)` 해야 하는 부분을 `template.update(sql, v1, v2, v3)` 로 처리했다.
★ ② `Member memberSelect(Member member)` 메소드 수정.
@Override
public Member memberSelect(Member member)
{
List<Member> members = null;
String sql = "SELECT *"
+ " FROM MEMBER"
+ " WHERE MEMID=?"
+ " AND MEMPW=?";
members = template.query(sql, new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement pstmt) throws SQLException
{
pstmt.setString(member.getMemId());
pstmt.setString(member.getMemPw());
}
}, new RowMapper<Member>() {
@Override
public Member mapRow(ResultSet rs, int rowNum) throws SQLException
{
Member mem = new Member();
mem.setMemId(rs.getString("MEMID"));
mem.setMemPw(rs.getString("MEMPW"));
mem.setMemMail(rs.getString("MEMMAIL"));
mem.setMemPurcNum(rs.getInt("MEMPURCNUM"));
return mem;
}
});
if (members.isEmpty())
return null;
return members.get(0);
}
[Check!!!]
▶ 『`PreparedStatementSetter()`』
- String으로 표현된 쿼리문의 ? 로 표현된 부분을 set 해 주기 위한 객체이다.
▶ 『`RowMapper()`』
- Database 에서 Select 를 통해 얻어온 회원 정보를 맵핑 해준다.
① 익명 클래스에서 사용할 때 값이 변경될 수 있으므로 `final String sql` 로 선언해도 된다.
final String sql = "SELECT *"
+ " FROM MEMBER"
+ " WHERE MEMID=?"
+ " AND MEMPW=?";
★② 두 번째 매개변수로 『`PreparedStatementSetter()`』 객체와 『익명 클래스』 를 선언해 준다.
members = template.query(sql, new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement pstmt) throws SQLException
{
pstmt.setString(member.getMemId());
pstmt.setString(member.getMemPw());
}
}, arg2);
▶ 익명 클래스 내부에서, `PreparedStatementSetter()` 의 메소드인
`void setValues(PreparedStatement pstmt)`를 `@Override` 해 준 후, 필요한 값을 채워준다.
★③ 세 번째 매개변수로 『`RowMapper<Member>()`』 객체와 『익명 클래스』 를 선언해 준다.
members = template.query(sql, new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement pstmt) throws SQLException
{
pstmt.setString(member.getMemId());
pstmt.setString(member.getMemPw());
}
}, new RowMapper<Member>() {
@Override
public Member mapRow(ResultSet rs, int rowNum) throws SQLException
{
Member mem = new Member();
mem.setMemId(rs.getString("MEMID"));
mem.setMemPw(rs.getString("MEMPW"));
mem.setMemMail(rs.getString("MEMMAIL"));
mem.setMemPurcNum(rs.getInt("MEMPURCNUM"));
return mem;
}
});
▶ 익명 클래스 내부에서, ` RowMapper()` 의 메소드인
`Object mapRow(ResultSet rs, int rowNum)`를 `@Override` 해 준 후,
`ResultSet` 에서 가져온 값들을 `member` 객체에 하나씩 set 하여 담아준다.
실행 결과 스크린샷
- 실행 결과는 이전과 동일하다. JdbcTemplate를 통해 코드 작성 단계에서의 반복을 없애준 것 뿐이다.
'[Inflearn] > 자바 스프링 프레임워크(renew ver.)' 카테고리의 다른 글
[inflearn] 20240121 [스프링-프레임워크] - 25강 필기 (0) | 2024.01.22 |
---|---|
[inflearn] 20240120 [스프링-프레임워크] - 23강 필기 (0) | 2024.01.21 |
[inflearn] 20240120 [스프링-프레임워크] - 21강 필기 (1) | 2024.01.20 |
[inflearn] 20240114 [스프링-프레임워크] - 20강 필기 (1) | 2024.01.14 |
[inflearn] 20240114 [스프링-프레임워크] - 19강 필기 (1) | 2024.01.14 |