JDBC 개발 - 등록, 수정, 조회, 삭제

Spring/Spring DB
2023. 9. 24. 01:10
목차
  1. 등록
  2. 조회
  3. 수정
  4. 삭제
728x90

 

JDBC를 사용해서 애플리케이션 개발해보기

회원 데이터를 데이터베이스에 관리하는 기능을 개발

 

Member

@Data
public class Member {
private String memberId;
private int money;
public Member() {
}
public Member(String memberId, int money) {
this.memberId = memberId;
this.money = money;
}
}

JDBC를 사용해서 이렇게 만든 회원 객체를 데이터베이스에 저장해보자.

 

등록

 

MemberRepositoryV0 - 회원 등록

@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 static Connection getConnection() {
return DBConnectionUtil.getConnection();
}
}

 

 

커넥션 획득

getConnection() : DBConnectionUtil 를 통해서 데이터베이스 커넥션을 획득한다.

//DBConnectionUtil
Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);

 

save() - SQL 전달

  • sql : 데이터베이스에 전달할 SQL을 정의한다. 여기서는 데이터를 등록해야 하므로 insert sql 을 준비 했다.
  • con.prepareStatement(sql) : 데이터베이스에 전달할 SQL과 파라미터로 전달할 데이터들을 준비한다.
  • pstmt.setString(1, member.getMemberId()) : SQL의 첫번째 ? 에 값을 지정한다. 문자이므로 setString 을 사용한다.
  • pstmt.executeUpdate() : Statement 를 통해 준비된 SQL을 커넥션을 통해 실제 데이터베이스에 전달한다. 참고로 executeUpdate() 은 int 를 반환하는데 영향받은 DB row 수를 반환한다. 여기서는 하나의 row를 등록했으므로 1을 반환한다.

 

리소스 정리

쿼리를 실행하고 나면 리소스를 정리해야 한다. 여기서는 Connection , PreparedStatement 를 사용했다.

리소스를 정리할 때는 항상 역순으로 해야한다.

Connection 을 먼저 획득하고 Connection 을 통해 PreparedStatement 를 만들었기 때문에 리소스를 반환할 때는 PreparedStatement 를 먼저 종료하고, 그 다음에 Connection 을 종료하면 된다.

 

주의할 점
리소스 정리는 꼭! 해주어야 한다. 따라서 예외가 발생하든, 하지 않든 항상 수행되어야 하므로 finally 구 문에 주의해서 작성해야한다. 만약 이 부분을 놓치게 되면 커넥션이 끊어지지 않고 계속 유지되는 문제가 발 생할 수 있다. 이런 것을 리소스 누수라고 하는데, 결과적으로 커넥션 부족으로 장애가 발생할 수 있다.

 

조회

public Member findById(String memberId) throws SQLException {
    String sql = "select * from member where member_id = ?";

    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;

    try {
        con = getConnection();
        pstmt = con.prepareStatement(sql);
        pstmt.setString(1, memberId);

        rs = pstmt.executeQuery(); // select 결과를 담고 있음
        if (rs.next()){
            Member member = new Member();
            member.setMemberId(rs.getString("member_id"));
            member.setMoney(rs.getInt("money"));
            return member;
        } else {
            throw new NoSuchElementException("member not found memberId=" + memberId);
        }

    } catch (SQLException e) {
        log.error("db error", e);
        throw e;
    } finally {
        close(con, pstmt, rs);
    }

}

 

findById() - 쿼리 실행

  • sql : 데이터 조회를 위한 select SQL을 준비한다.
  • rs = pstmt.executeQuery() : 데이터를 변경할 때는 executeUpdate() 를 사용하지만, 데이터를 조회 할 때는 executeQuery() 를 사용한다. executeQuery() 는 결과를 ResultSet 에 담아서 반환한다

 

ResultSet

  • ResultSet 은 다음과 같이 생긴 데이터 구조이다. 보통 select 쿼리의 결과가 순서대로 들어간다.
    • 예를 들어서 select member_id, money 라고 지정하면 member_id , money 라는 이름으로 데이터 가 저장된다.
  • ResultSet 내부에 있는 커서( cursor )를 이동해서 다음 데이터를 조회할 수 있다.
  • rs.next() : 이것을 호출하면 커서가 다음으로 이동한다. 참고로 최초의 커서는 데이터를 가리키고 있지 않기 때문에 rs.next() 를 최초 한번은 호출해야 데이터를 조회할 수 있다
    • rs.next() 의 결과가 true 면 커서의 이동 결과 데이터가 있다는 뜻이다.
    • rs.next() 의 결과가 false 면 더이상 커서가 가리키는 데이터가 없다는 뜻이다
  • rs.getString("member_id") : 현재 커서가 가리키고 있는 위치의 member_id 데이터를 String 타입으로 반환한다.

findById에서는 회원 한명을 조회하는 것이므로 while문 대신 if문을 사용해서 id가 일치하는 회원이 있는지 확인하는 로직이다.

 

수정

public void update(String memberId, int money) throws SQLException {
    String sql = "update member set money=? where member_id=?";

    Connection con = null;
    PreparedStatement pstmt = null;

    try {
        con = getConnection();
        pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, money);
        pstmt.setString(2, memberId);
        int resultSize = pstmt.executeUpdate(); //executeUpdate() 는 쿼리를 실행하고 영향받은 row수를 반환한다
        log.info("resultSize={}", resultSize);
    } catch (SQLException e) {
        log.error("db error", e);
        throw e;
    } finally {
        close(con, pstmt, null);

    }
}

 

삭제

public void delete(String memberId) throws SQLException {
    String sql = "delete from member where member_id=?";

    Connection con = null;
    PreparedStatement pstmt = null;

    try {
        con = getConnection();
        pstmt = con.prepareStatement(sql);
        pstmt.setString(1, memberId);
        pstmt.executeUpdate(); //executeUpdate() 는 쿼리를 실행하고 영향받은 row수를 반환한다
    } catch (SQLException e) {
        log.error("db error", e);
        throw e;
    } finally {
        close(con, pstmt, null);

    }
}

 

테스트를 2번 연속 실행하면 pk 중복 오류가 발생하므로 delete쿼리를 사용해서 데이터를 삭제하는 로직을 만들었다.

728x90

'Spring > Spring DB' 카테고리의 다른 글

JDBC에 의존하는 트랜잭션을 적용하면서 나타나는 문제점  (0) 2023.10.03
트랜잭션  (1) 2023.10.02
커넥션 풀과 데이터소스 이해  (0) 2023.09.29
H2 데이터베이스 연결  (0) 2023.09.24
JDBC의 이해  (0) 2023.09.24
  1. 등록
  2. 조회
  3. 수정
  4. 삭제
'Spring/Spring DB' 카테고리의 다른 글
  • 트랜잭션
  • 커넥션 풀과 데이터소스 이해
  • H2 데이터베이스 연결
  • JDBC의 이해
hapBday
hapBday
hapBday
개발자로 성장하기 위한 기록들
hapBday
전체
오늘
어제
  • 분류 전체보기 (203)
    • CS (12)
      • 컴퓨터네트워크 (11)
      • 운영체제 (0)
      • 분산 시스템 (0)
      • 데이터베이스 (1)
    • Spring (47)
      • Spring 핵심 원리 (13)
      • Spring MVC (15)
      • Spring DB (12)
      • Spring Security (6)
    • JPA (14)
    • 알고리즘 (30)
      • 프로그래머스 (6)
      • 백준 (20)
    • Design Pattern (0)
    • 언어 (5)
      • JAVA (5)
    • ASAC 웹 풀스택 (38)
      • Spring Boot (21)
      • React (0)
      • DevOps (8)
    • 트러블슈팅 (15)
    • DevOps (5)
      • Docker (5)
    • ETC (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • github

공지사항

  • 블로그 이전

인기 글

태그

  • docker
  • 백준
  • S3
  • 프로그래머스
  • s-lock
  • docker workflow
  • 인프런
  • Spring
  • currency control
  • multi-stage
  • x-lock
  • CSRF
  • 티스토리챌린지
  • basicerrorcontroller
  • Session
  • 트랜잭션
  • cookie
  • 김영한
  • MVC
  • 구현
  • aws lambda
  • 3-layerd 아키텍쳐 패턴
  • CORS
  • spring boot
  • JPA
  • docker best practices
  • Java
  • 오블완
  • spring security
  • jwt

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.3.0
hapBday
JDBC 개발 - 등록, 수정, 조회, 삭제
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.