๐ฑSpring H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์น์ ์์ JDBC
์ธํ๋ฐ ์คํ๋ง ์ ๋ฌธ ๊ฐ์๋ฅผ ๋ณด๊ณ ์คํ๋ง์ ๊ณต๋ถ ํ ๊ธฐ๋ก์ฉ์ผ๋ก ์์ฑํฉ๋๋ค
1. H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์น
h2๋ฅผ ์ค์นํฉ๋๋ค ๋ฒ์ ์ ๊ฐ์์ ๋์จ๋๋ก 1.4.200 ๋ฒ์ ์ผ๋ก ๋ค์ด ๋ฐ์์ต๋๋ค ๊ทธ๋ค๋ก ์คํ๋ง ํ๋ก์ ํธ๊ฐ ์๋ Spring_std์ ์์ถ์ ํด์ ํ์ต๋๋ค
C:\Spring_std\H2\bin>h2.bat
cmd์ฐฝ์์ h2๋ฅผ ์คํํฉ๋๋ค
์๋์ฐ๋ h2.bat ์ผ๋ก ์คํํฉ๋๋ค
์คํํ๋ฉด ์๋์ผ๋ก ์น๋ธ๋ผ์ฐ์ ํ์ด์ง๊ฐ ๋์ต๋๋ค
ํ์ฌ ์ํ๋ก ์ต์ด๋ก ์ฐ๊ฒฐ ํด์ค๋๋ค
์๋จ ์ผ์ชฝ์ ์๋ ๋นจ๊ฐ ์ ๋๊ฐ๋ก ๋ค์ ์ฒ์ ํ๋ฉด์ผ๋ก ๋์์
JDBC URL : ์ด๋ถ๋ถ์ ์๋์ ๊ฐ์ด ์
๋ ฅํ์ฌ
jdbc:h2:tcp://localhost/~/test
๋ค์ ํ๋ฒ ์ฐ๊ฒฐํด์ค๋๋ค
๊ทธ๋ฌ๋ฉด ๋๋น ์ฐ๊ฒฐ์ด ๋์์ต๋๋ค
member ํ ์ด๋ธ์ ์์ฑ ํ์ต๋๋ค
create table member
(
id bigint generated by default as identity,
name varchar(255),
primary key (id)
);
๊ฐ์ ๋ฃ๊ธฐ ์ํด insert ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ ธ์ต๋๋ค
insert into member(name) values('spring')
์ ๊ฒฐ๊ณผ๋๋ก ๋๋น์ ์ ๋ค์ด๊ฐ๊ฑธ ํ์ธํ ์ ์์์ต๋๋ค
2. ์์ JDBC
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa //์ถ๊ฐ
spring.datasource.password= //์ถ๊ฐ
์ฒ์์ ์ฝ๋๊ฐ ๋์ค์ด์๋๋ฐ ์ค๋ฅ๊ฐ ๋ฌ๋๋
์ ์ ๋ค์๊ณผ ํจ์ค์๋๊น์ง ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค๋ ์ต๋ช
๋ ๋์!
์ถ๊ฐํ๋๋ ์ค๋ฅ๊ฐ ๋์ง ์๊ณ ์ ์คํ์ด๋ฉ๋๋ค
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);
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);
}
}
SpringConfig
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
@Autowired
DataSource dataSource;
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
return new JdbcMemberRepository(dataSource);
}
}
์ฃผ์ ํ๋ ๋ฐฉ๋ฒ ์ค ํ๊ฐ์ง ๋ฐฉ๋ฒ์ ํํ์ต๋๋ค
@Autowired
DataSource dataSource;
return new JdbcMemberRepository(dataSource);
MemberRepository ์์ฑ์ ํธ์ถ ํ ๋ JdbcMemberRepository ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ์ต๋๋ค
ํ์๋ชฉ๋ก์ ๋ค์ด๊ฐ๋ฉด ๊ฒฐ๊ณผ๊ฐ ์๋์ต๋๋ค
์คํ๋ง์ DI (Dependencies Injection)์ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด ์ฝ๋๋ฅผ ์ ํ ์๋์ง ์๊ณ , ์ค์ ๋ง์ผ๋ก ๊ตฌํ ํด๋์ค๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค
์๋ ๊ฐ๋ฐ์๋ถ๋ค์ ์ผ์ผ์ด ์ฝ๋ฉํ๋๋ผ ํ๋ค์ด๊ฒ ๋ค... ๋ผ๋ ์๊ฐ์ด ๋ค์์ต๋๋ค ์คํ๋ง์ ์ข ๋ ๊ฐ๊น์์ก์ต๋๋ค ๊ฐ์ฌํฉ๋๋ค
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ฑSpring H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์น์ ์์ JDBC), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@haezzang/Spring-H2-๋ฐ์ดํฐ๋ฒ ์ด์ค-์ค์น์-์์-JDBC์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค