JDBC로 Member 데이터를 데이터베이스에 관리하는 기능을 개발
주의
H2 데이터베이스 설정 마지막에 있는 테이블과 샘플 데이터 만들기를 통해서 member
테이블을 미리 만들어야 함
drop table member if exists cascade;
create table member (
member_id varchar(10),
money integer not null default 0,
primary key (member_id)
);
@Data
: Getter, Setter, RequiredArgsConstructor, ToString, EqualsAndHashCode, Value 자동으로 생성해줌package hello.jdbc.domain;
import lombok.Data;
@Data
public class Member {
private String memberId;
private int money;
public Member() {
}
public Member(String memberId, int money) {
this.memberId = memberId;
this.money = money;
}
}
package hello.jdbc.repository;
// JDBC : DriverManger 사용
import hello.jdbc.connection.DBConnectionUtil;
import hello.jdbc.domain.Member;
import lombok.extern.slf4j.Slf4j;
import java.sql.*;
@Slf4j
public class MemberRepositoryV0 {
public Member save(Member member) throws SQLException{
String sql = "insert into member(member_id, money) values (?, ?)";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, member.getMemberId());
pstmt.setInt(2, member.getMoney());
pstmt.executeUpdate();
return member;
} catch (SQLException e) {
log.error("db error", e);
throw e;
} finally {
close(con, pstmt, null);
}
}
private void close(Connection con, Statement stmt, ResultSet rs) {
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
log.info("error", e);
}
}
if(stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
log.info("error", e);
}
}
if(con != null) {
try {
con.close();
} catch (SQLException e) {
log.info("error", e);
}
}
}
private Connection getConnection() {
return DBConnectionUtil.getConnection();
}
}
커넥션 획득
DBConnectionUtil 클래스
의 getConnection()
을 통해 데이터베이스 커넥션 획득save() - SQL 전달
sql
insert sql
con.prepareStatement(sql)
: 데이터베이스에 전달할 SQL과 파라미터로 전달할 데이터들 준비sql
: insert into member(member_id, money) values(?, ?)
pstmt.setString(1, member.getMemberId())
: SQL의 첫번째 ?에 값을 지정, 문자이므로 setString
pstmt.setString(2, member.getMoney())
: SQL의 두번째 ?에 값을 지정, 정수형이므로 setInt
pstmt.executeUpdate()
Statement
를 통해 준비된 SQL을 커넥션을 통해 실제 데이터베이스에 전달executeUpdate()
는 영향받은 DB row 수를 int
로 반환리소스 정리
Connection
먼저 획득 후 PreparedStatement
만들었음PreparedStatement
먼저 종료 후 Connection
종료주의
finally
구문에서 작성리소스 누수
라고 함참고
PreparedStatement
는 Statement
의 자식 타입?
를 통한 파라미터 바인딩PreparedStatement
를 통한 파라미터 바인딩 방식을 사용해야 함package hello.jdbc.repository;
import hello.jdbc.domain.Member;
import org.junit.jupiter.api.Test;
import java.sql.SQLException;
import static org.junit.jupiter.api.Assertions.*;
class MemberRepositoryV0Test {
MemberRepositoryV0 repositoryV0 = new MemberRepositoryV0();
@Test
void crud() throws SQLException {
Member member = new Member("memberV1", 10000);
repositoryV0.save(member);
System.out.println(member);
}
}
테스트 코드 실행 결과