You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
packagehello.jdbc.repository;
importlombok.extern.slf4j.Slf4j;
/*** JDBC = DriverManager 사용**/@Slf4jpublicclassMemberRepositoryV0 {
publicMembersave(Membermember) throwsSQLException {
Stringsql = "insert into member(member_id, money) values (?, ?);"Connectioncon = null;
PreparedStatementpstmt = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, member.getMemberId());
pstmt.setInt(2, member.getMoney());
returnmember;
}catch (SQLExceeptione){
//checked Exceptionlog.error("db error", e);
//e.printStackTrace();throwe;
}finally {
//시작과 역순으로 닫는다.// pstmt.close(); //Exception 되면 con이 닫히지않는 문제가 발생할 수 있다.// con.close();close(con, pstmt, null);
}
}
privatevoidclose(Connectioncon, Statementstmt, ResultSetrs) {
if(rs!= null) {
try {
rs.close();
catch (SQLExceptione) {
log.info("error", e);
}
}
if(stmt != null) {
try {
stmt.close(); //pstmt 는 파라미터를 넘길 수 있는 더 많은 기능을 가지고 있고 stmt를 상속받는다catch (SQLExceptione) {
log.info("error", e);
}
}
// 이렇게 하면 각자 에러가 터져도 다른 것에 영향을 주지 않기에 닫을 수 있다.if(con != null) {
try {
con.close();
}catch (SQLExceptione) {
log.info("error", e);
}
}
privateConnectiongetConnection() {
returnDBConnectionUtil.getConnection();
}
}
커넥션 획득
getConnection() : 이전에 만들어둔 DBConnectionUtil 을 통해서 데이터 베이스 커넥션을 획득한다.
save() : SQL 전달
sql : 데이터 베이스에 전달할 SQL 을 정의한다. 여기서는 데이터를 등록해야 하므로 insert sql을 했다.
con.prepareStatement(sql) : 데이터 베이스에 전달할 SQL과 파라미터로 전달할 데이터들을 준비한다.
pstmt.executeUpdate() : Statement 를 통해 준비된 SQL을 커넥션을 통해 실제 데이터 베이스에 전달한다. 참고로 executeUpdate() 는 int를 반환하는데 영향받은 DB row 수를 반환한다. 여기서는 하나의 row를 등록했으므로 1을 반환한다.
executeUpdate()
intexecuteUpdate() throwsSQLException;
리소스 정리
쿼리를 실행하고 나면 리소스를 정리해야 한다. 여기서는 Connection, PreparedStatement 를 사용했다. 리소스를 정리할 때는 항상 역순으로 해야한다. Connection을 먼저 획득하고 Connection을 통해 PreparedStatement 를 만들었기 때문에 리소스를 반환할때는 PreparedStatement를 먼저 종료하고 그 다음, Connection을 종료하면 된다. 여기서는 사용하지 않은 ResultSet은 결과를 조회할때 사용한다.
!! 리소스 정리는 꼭해야한다. 안하면 리소스 누수로 인해 커넥션 부족으로 장애가 발생할 수 있다.
참고 PreparedStatement는 Statement의 자식타입인데, ? 를 통한 파라미터 바인딩을 가능하게 해준다. 참고로 SQL Injection 공격을 예방하려면 PrepareStatement를 통한 파라미터 바인딩 방식을 사용해야 한다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
JDBC 개발 - 등록
JDBC를 사용해서 회원 데이터를 데이터베이스에 관리하는 기능을 개발해본다.
주의 ~
H2데이터베이스 설정 마지막에 있는 테이블과 샘플 데이터 만들기를 통해서
member테이블을 미리 만들어두어야 한다.package : repository
MemberRepositoryV0커넥션 획득
getConnection(): 이전에 만들어둔DBConnectionUtil을 통해서 데이터 베이스 커넥션을 획득한다.save() : SQL 전달
sql: 데이터 베이스에 전달할 SQL 을 정의한다. 여기서는 데이터를 등록해야 하므로 insert sql을 했다.con.prepareStatement(sql): 데이터 베이스에 전달할 SQL과 파라미터로 전달할 데이터들을 준비한다.pstmt.executeUpdate(): Statement 를 통해 준비된 SQL을 커넥션을 통해 실제 데이터 베이스에 전달한다. 참고로executeUpdate()는int를 반환하는데 영향받은 DB row 수를 반환한다. 여기서는 하나의 row를 등록했으므로 1을 반환한다.executeUpdate()
리소스 정리
쿼리를 실행하고 나면 리소스를 정리해야 한다. 여기서는 Connection, PreparedStatement 를 사용했다. 리소스를 정리할 때는 항상 역순으로 해야한다. Connection을 먼저 획득하고 Connection을 통해 PreparedStatement 를 만들었기 때문에 리소스를 반환할때는 PreparedStatement를 먼저 종료하고 그 다음, Connection을 종료하면 된다. 여기서는 사용하지 않은
ResultSet은 결과를 조회할때 사용한다.JDBC 개발 - 조회
executeUpdate()를 사용하지만 데이터를 조회할 때는executeQuery를 사용한다.executeQuery()는 결과를 ResultSet에 담아서 반환한다.exeuteQuery()
ResultSet
ResultSet은 다음과 같이 생긴 데이터 구조이다. 보통 select 쿼리의 결과가 순서대로 들어간다.ResultSet내부에 있는 커서(cursor)를 이동해서 다음 데이터를 조회할 수 잇따.rs.next(): 이것을 호출하면 커서가 다음으로 이동한다. 참고로 최초의 커서는 데이터를 가리키고 있지 않기 때문에rs.next()룰 최초 한번은 호출해야 데이터를 조회할 수 있다.member_id데이터를String타입으로 반환한다.ResultSet 결과 예시
Test
실행 결과에 member객체의 참조값이 아니라 실제 데이터가 보이는 이유는 @DaTa가 toString() 을 적절히 오버라이딩해서 보여주기 때문이다.
@lombok을 쓰면
equals&hashCode를 잡아준다.isEqualTo():findMember.equals(member)를 비교한다. 결과가 참인 이유는 롬복의@Data는 해당 객체의 모든 필드를 사용하도록equals()를 오버라이딩하기 때문이다.JDBC 개발 - 수정, 삭제
Test
실행로그(pstmt.executeUpdate()의 결과)
findById()를 통해서 조회한다. 회원이 없기 때문에NoSuchElementException이 발생한다.assertThatThrownBy는 해당 예외가 발생해야 검증에 성공한다.All reactions