옛날에 쓰던 방식.
build.gradle에 라이브러리를 추가 해야 함.
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
spring.datasource.username=sa
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
기본적으로 java에서 db 쓸려면 저게 필요함.
runtimeOnly 'com.h2database:h2'
h2 db를 쓴다.
저거 해주고 gradle 새로고침 해줘야 적용됨. 아마 저 정보보고 웹에서 다운로드? 인듯.
spring.datasource.username=sa
이것도 써야 함.
G:\spring\hello-spring\src\main\resources\application.properties
여기에다가 db 접속정보를 넣어줘야 함.
현재는 경로만 넣어주면 됨.
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
전에 h2 접속할 때 경로.
spring.datasource.driver-class-name=org.h2.Driver
h2 쓴다고
이거 h2 접속해보면 연결하기 전에 다 써있음.
원래는 id, 비밀번호도 적고 하는데, h2에선 일단 생략.
public class JdbcMemberRepository implements MemberRepository{
private final DataSource dataSource; //db 쓸려면 dataSource 필요
public JdbcMemberRepository(DataSource dataSource) { //나중에 spring 에서부터 주입받도록
this.dataSource = dataSource;
}
@Override
public Member save(Member member) {
String sql = "insert into member(name) values(?)"; //save 쿼리. 이거는 상수로 빼는게 낫긴 함. ?는 바인딩.
Connection conn = null; //커넥트 가져옴
PreparedStatement pstmt = null; //문장 작성
ResultSet rs = null; //이건 결과 받는 거
try{ //얘네 예외 엄청 떠서 try catch 잘 해야 함.
conn = getConnection(); //커넥션 얻어 오고
pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); //문장 작성
pstmt.setString(1, member.getName()); //?에 삽입
pstmt.executeUpdate(); // 쿼리 날리기
rs = pstmt.getGeneratedKeys(); //RETURN_GENERATED_KEYS 반환
if(rs.next()){ //next에 값이 있는지 검사. 처음이 0이 아니라 0 이전이라 next가 0번째임.
member.setId(rs.getLong(1));
} else{
throw new SQLException("id 조회 실패");
}
return member;
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs); //DB 커넥션은 다 쓰면 바로 끊어 줘야 함. 아니면 계속 쌓이다가 참사가 일어날 수도..
}
}
@Override
public Optional<Member> findById(Long id) {
String sql = "select * from member where id = ?"; //save 쿼리. 이거는 상수로 빼는게 낫긴 함.
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null; //이건 결과 받는 거
try{
conn = getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setLong(1,id);
rs = pstmt.executeQuery(); //삽입이 아닌 조회는 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 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);
} 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);
}
}
private Connection getConnection(){
return DataSourceUtils.getConnection(dataSource); //스프링에서 DB 커넥션을 쓸거면 DataSourceUtils를 통해 획득 해야 한다.
}
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); //닫을 때도 스프링에서는 releaseConnection를 통해 닫아야 함.
}
}
이거 고전버전.
@Configuration
public class SpringConfig {
private DataSource dataSource;
@Autowired
public SpringConfig(DataSource dataSource){
this.dataSource = dataSource;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
// @Bean
// public MemberRepository memberRepository(){
// return new MemoryMemberRepository();
// }
@Bean
public MemberRepository memberRepository(){
return new JdbcMemberRepository(dataSource);
}
}
SpringConfig.java임.
저렇게 기존 MemberRepopsitory에서 Jdbc로 바꿔 끼워주면 됨.
참고로,
@Autowired
public SpringConfig(DataSource dataSource){
this.dataSource = dataSource;
}
이거 같은 경우, @Autowired 해주면,
알아서 스프링이
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
application.properties에서 DataSource 찾아서 넣어줌.
'스프링 > 0. 입문, 전체방향' 카테고리의 다른 글
18강. Jdbc 템플릿 (0) | 2023.07.09 |
---|---|
17강. spring 종합 테스트 (0) | 2023.07.09 |
15강. H2 DB (0) | 2023.07.08 |
14강. 간단한 웹 기능 -조회 (0) | 2023.07.08 |
13강. 간단 회원 웹 기능 -등록 (0) | 2023.07.08 |