-
20강. 순수 JDBC스프링 프레임워크-입문 2021. 5. 6. 10:13
애플리케이션에서 DB를 연결해보는 기술인 JDBC를 사용해보겠습니다. JDBC는 매우 오래된 기술입니다.
자바는 DB랑 연결을 하려면 JDBC 드라이버가 꼭 있어야 합니다. 그리고 H2 라이브러리를 추가해주도록 하겠습니다.
DB에 접속하기 위한 접속 정보입니다.
(url, dirver-class-name, username, password) 이정도를 입력을 해야합니다.
이제는 DB를 설정했기 때문에 MemoryRepository의 구현체를 만들어야 합니다. 그래서 JdbcMemoryRepository를 만들도록 하겠습니다.
인터페이스를 구현한 후 메소드를 오버라이드 했습니다,
시간이 상당히 소요되기 때문에 우리는 복사 붙여넣기를 하면서 진행하도록 하겠습니다.
DB와 연결하기 위해서는 DataSource를 가져와야합니다. 그래서 위의 코드를 추가하겠습니다.
1차적으로 코드를 완성했습니다. SQL 구문을 선언한 후 연결을 하고 구문을 준비시킨다음 실행시키는 과정입니다.
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); pstmt.setString(1, member.getName()); pstmt.executeUpdate(); rs = pstmt.getGeneratedKeys(); 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); } }
JDBC는 지금 사용하지 않는 기술이기에 이해만 하기위해서 위의 코드를 추가해줍니다.
결과를 받기위한 ResultSet 선언
우리가 설정한 Sequence를 DB에서 값을 반환해 오기 위한 코드
파라미터 인덱스가
아래와 매칭이 되어 member.getName()이 들어가게 됩니다.
DB에 실지 SQL 구문이 날라가게 됩니다.
DB가 생성한 키를 반환합니다. (ID)
rs가 값을 반환해 오는 것을 조회합니다.
DB와 연결하는 구문은 Exception을 많이 던지기 때문에 try~catch문을 구현을 해야합니다. 또한 외부 네트워크와 연결하는 방식이기 때문에 무조건 자원을 release해주어야 합니다.
다른 메서드들도 많이 다르지 않습니다.
코드를 완성했기 때문에 연결해주기 위해서 SpringConfig에서 수정을 해주도록 합니다.
하지만 여기서 문제가 발생합니다. 우리는 JdbcMemoryRepository에서 생성자에서 datasource를 받기 때문에 코드를 한 차례 더 수정합니다.
서버를 재가동하면 정상적으로 실행되는 것을 확인할 수 있습니다.
우리가 전 장에서 입력한 것이 확인이 가능합니다. 우리는 또 다른 기능인 등록을 수행해보도록 하겠습니다.
제가 추가로 입력한 jpa와 Danny까지 잘 들어가는 것을 체크했습니다.
Spring의 장점이 이런 방식입니다.(다형성) 우리는 다른 코드들을 손 대지 않고 MemoryRepository와 JdbcMemoryRepository를 바꿔끼면 정상적으로 동작이 가능합니다.
이러한 것을 어셈블리라고합니다. 조립한다는 의미인데 코드를 크게 손대지 않고도 구동이 가능하다는 것이 Spring의 ㅣ장점입니다.
개방-폐쇄 원칙(OCP, Open-Closed Principle)
- 확장에는 열려있고, 수정-변경에는 닫혀있다.
- 객체지향에서의 다형성을 잘 활용을 하면 기능을 변경을 해도 전체적인 코드를 하나도 변경하지 않을 수 있습니다.
스프링 DI(Dependency Injection)
- 을 사용하면 기존 코드를 전혀 손대지 않고, 설정만으로 구현 클래스를 변경할 수 있습니다.
- 스프링을 종료해도 DB에 저장을 하기 때문에 DB를 종료하기 전까지 데이터를 안전하게 보관할 수 있습니다.
'스프링 프레임워크-입문' 카테고리의 다른 글
22강. 스프링 Jdbc Template (0) 2021.05.06 21강. 스프링 통합 테스트 (0) 2021.05.06 19강. H2 데이터베이스 설치 (0) 2021.05.05 18강. 회원 웹 기능 - 조회 (0) 2021.05.05 17강. 회원 웹 기능 - 등록 (0) 2021.05.05