스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - (순수 JDBC)

홍범선·2023년 4월 29일
0

스프링

목록 보기
19/35

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - (순수 JDBC)

  1. build.gradle파일 추가

    jdbc와 h2관련코드 추가
    자바는 DB랑 붙으려면 jdbc 드라이버가 꼭 있어야 함 또한 DB 붙으려면 접속 정보 넣어야 함

  2. Spring부트에서는 접속 정보만 입력해주면 DB접속 가능

application.properties에 다음과 같이 입력
만약 빨간줄 뜨면 gradle 최신화 안된 것이므로 build.gradle에서 꼬끼리 모양 버튼 클릭
하지만 스프링 2.4부터 username은 꼭 작성해야함

  1. spring은 인터페이스등 다향성 부분이 좋음 객체지향적 기능을 완전히 변경해도 config부분만 수정하면 됨

4.MemoryMemberRepository가 아니라 JDBCMemberRepository를 생성한다.

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.springframework.jdbc.datasource.DataSourceUtils;
import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class JdbcMemberRepository implements MemberRepository {
    private final DataSource dataSource;

    public JdbcMemberRepository(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public Member save(Member member) {
        String sql = "insert into member(name) values(?)";

        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null; // 결과를 받음음

       try {
            conn = getConnection(); //커넥션을 가지고 옴
            pstmt = conn.prepareStatement(sql,
                    Statement.RETURN_GENERATED_KEYS); // ID값을 생성함
            pstmt.setString(1, member.getName());
            pstmt.executeUpdate();
            rs = pstmt.getGeneratedKeys(); // ID값을 반환함
            if (rs.next()) {
                member.setId(rs.getLong(1));
            } else {
                throw new SQLException("id 조회 실패");
            }
            return member;
        } catch (Exception e) {
            throw new IllegalStateException(e);
        } finally {
            close(conn, pstmt, rs); //자원 끊어야 함 메모리를 차지하기 떄문
        }
    }

    @Override
    public Optional<Member> findById(Long id) {
        String sql = "select * from member where id = ?";
        Connection conn = null;
        PreparedStatement pstmt = null;

        ResultSet rs = null;
        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            pstmt.setLong(1, id);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                Member member = new Member();
                member.setId(rs.getLong("id"));
                member.setName(rs.getString("name"));
                return Optional.of(member);
            } else {
                return Optional.empty();
            }
        } catch (Exception e) {
            throw new IllegalStateException(e);
        } finally {
            close(conn, pstmt, rs);
        }
    }

    @Override
    public List<Member> findAll() {
        String sql = "select * from member";
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();

            List<Member> members = new ArrayList<>();
            while (rs.next()) {
                Member member = new Member();
                member.setId(rs.getLong("id"));
                member.setName(rs.getString("name"));
                members.add(member);
            }
            return members;
        } catch (Exception e) {
            throw new IllegalStateException(e);
        } finally {
            close(conn, pstmt, rs);
        }
    }

    @Override
    public Optional<Member> findByName(String name) {
        String sql = "select * from member where name = ?";
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, name);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                Member member = new Member();
                member.setId(rs.getLong("id"));
                member.setName(rs.getString("name"));
                return Optional.of(member);
            }

            return Optional.empty();
        } catch (Exception e) {
            throw new IllegalStateException(e);
        } finally {
            close(conn, pstmt, rs);
        }
    }

    private Connection getConnection() { //스프링은 이렇게 연결해야함
        return DataSourceUtils.getConnection(dataSource);
    }

    private void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (pstmt != null) {
                pstmt.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (conn != null) {
                close(conn);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private void close(Connection conn) throws SQLException { //스프링은 이렇게 닫아야함
        DataSourceUtils.releaseConnection(conn, dataSource);
    }
}

여기서 getConnection, close부분은 중요하지만 나머지 부분은 현재 이렇게 사용하고 있지 않다.

  1. config 파일 수정

    기존에는 Memory로 되어 있었지만 Jdbc로만 변경해주면 된다.
    그리고 dataSource도 DI로 하여 넣어준다. 이렇게 해야지 하나의 dataSource로 모든 코드에서 사용할 수 있다.
profile
알고리즘 정리 블로그입니다.

0개의 댓글