(스프링 DB 접근 기술을 몇 차례에 나누어 진행하도록 하겠습니다)
지금까지는 따로 회원 정보를 DB에 저장해두지 않아 껐다 키면 서버가 날아가 회원 목록이 전부 사라졌습니다
데이터가 날아가지 않도록 H2 데이터베이스 설치를 하도록 하겠습니다
그리고 설치한 DB를 JDBC로 연결하여 사용해보도록 하겠습니다
H2 데이터베이스 설치
: 개발이나 테스트 용도로 가볍고 편리한 DB, 웹 화면 제공
https://www.h2database.com 에 접속하여 다운로드 및 설치
h2 데이터베이스 버전은 스프링 부트 버전에 맞춘다
권한 주기 : chmod 755 h2.sh <- 윈도우는 안해도 됨
실행 : ./h2.sh
데이터 베이스 파일 생성 방법
jdbc:h2:~/test (최초 한 번)
이후 부터는 jdbc:h2:tcp://localhost/~/test 이렇게 접속

우선 사이트에 접속하여 설치파일을 다운로드 합니다
처음에는 다운을 받고 ./h2.sh 로 실행을 시켜봤지만 실행이 되지 않았습니다
압축을 풀고 h2w.bat 파일을 클릭하면 H2 서버가 구동되어 자동으로

이렇게 화면이 나타났습니다!!!
우선 최초에는 데이터베이스 파일이라는 것을 만들어야 합니다
( JDBC URL 오른쪽은 나의 test 파일의 경로를 나타낸다

[ H2 데이터베이스에 접근해서 member 테이블 생성 ]
create table member
(
id bigint generated by default as identity,
name varchar(255),
primary key (id)
);
1. 자신의 파일에 test.mv.db가 있는지 확인을 한다
2. JDBC URL을 바꾼다 -> jdbc:h2:tcp://localhost/~/test
3. 실행을 누른 뒤 테이블을 만든다

4. table을 하나 만들어주었다
왼쪽에 노랑 형광펜으로 칠한 MEMBER 테이블이 만들어졌다면 성공!
| 자바에서 id는 long이었지만 DB에서는 bigint로 사용 generated by default as identity 는 만약 값을 주지 않고 insert하면 DB가 자동으로 값을 채워준다 그리고 pk는 id로 주었다 |

한 번 insert 해보도록 하겠습니다 ^^
insert into member(name) values('spring')
이렇게 insert하고 select로 조회를 하고 나면 출력이 됩니다

참고로 ./h2.sh 로 실행을 시킨 DB를 끄면 H2 database가 실행되지 않습니다
웹 콘솔을 통해 DB에 접속을 해보았고 이제 앱플리케이션을 통해 DB에 삽입을 해보도록 하겠습니다
순수 JDBC
환경설정
bulid.gradle 파일에 jdbc, h2 데이터베이스 관련 라이브러리 추가
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'

spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
application.properties에 위 내용을 추가하고
다시 bulid.gradle파일에 가서

노란 동그라미를 클릭하면 드라이브 세팅 완료.
(이제 DB에 접근할 수 있습니다)

JdbcMemberRepository에 들어가는 내용입니다
package com.ujin.ujinspring.repository;
import com.ujin.ujinspring.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);
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);
}
}
save하기 위한 쿼리문, 데이터베이스를 가져오기 위한 conn 등을 사용하여 DB에 쿼리문을 날려준다
안에 내용을 추가한 뒤
SpringConfig에 가서 이렇게 변경해줍니다
package com.ujin.ujinspring.service;
import com.ujin.ujinspring.repository.JdbcMemberRepository;
import com.ujin.ujinspring.repository.MemberRepository;
import com.ujin.ujinspring.repository.MemoryMemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
private DataSource dataSource;
@Autowired
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
// return new MemoryMemberRepository();
return new JdbcMemberRepository(dataSource);
}
}
DataSource는 데이터베이스 커넥션을 획득할 때 사용하는 객체다. 스프링 부트는 데이터베이스 커넥션 정보를 바탕으로 DataSource를 생성하고 스프링 빈으로 만들어둔다. 그래서 DI를 받을 수 있다


개방.패쇄 원칙(,OCP, Open-Closed Principle)
- 확장에는 열려있고, 수정에는 닫혀있다
스프링의 DI(Dependencies Injection)을 사용하면 기존 코드를 전혀 손대지 않고, 설정만으로 구현 클래스를 변경할 수 있다
회원을 등록하고 DB에 결과가 잘 입력되는지 확인,
데이터를 DB에 저장하므로 스프링 서버를 다시 실행해보 데이터가 안전하게 저장됨
'Spring' 카테고리의 다른 글
| 스프링 DB 접근 기술 3 ( JPA | 스프링 데이터 JPA ) (0) | 2022.01.28 |
|---|---|
| 스프링 DB 접근 기술 2 ( 스프링 통합 테스트 | 스프링 JdbcTemplate ) (0) | 2022.01.27 |
| 회원 관리 예제 - 웹 MVC 개발 ( 회원 웹 기능 - 홈 화면 추가 | 등록 | 조회 ) (0) | 2022.01.25 |
| 스프링 빈과 의존관계 ( 컴포넌트 스캔과 자동 의존관계 설정 | 자바 코드로 직접 스프링 빈 등록하기 ) (0) | 2022.01.24 |
| 회원 관리 예제 2 - 백엔드 개발 ( 회원 서비스 개발 | 회원 서비스 테스트 ) (0) | 2022.01.21 |