* 인프런 김영한 강사님의 스프링 입문 강의 정리
데이터 베이스를 설치했으므로 이제 스프링과 연결한다.
순수 jdbc와 jdbcTemplate을 사용하는 방법을 학습하였는데
jdbcTemplate을 중심으로 정리하려고 한다.
2. build.gradle에 라이브러리 추가
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
3. application.properties에 라이브러리 추가
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
build.gradle과 application.properties에 DB와 JDBC 사용을 위한 환경설정을 해주고 나면
스프링과 DB연결이 된다.
이제 할 일은 JDBC 리포지토리를 구현하는 것이다.
처음 DB가 연결되지 않았을 때에는 memoryMemberRepository를 생성하여 메모리 저장소에 데이터를 저장하였다.
이제 DB가 연결되었으니 JDBC Repository를 사용하고 스프링 빈 설정을 변경해주어야 한다.
4. JDBC Repostory 생성
JdbcMemberRepository는 순수 JDBC를 JdbcTemplateMemberRepository는 JdbcTemplate을 이용한 구현체이다.
JdbcTemplate은 JDBC 코어 패키지의 중앙 클래스로 순수 JDBC보다 훨씬 간편하게 코드를 작성할 수 있도록 도와준다.
여기서는 JdbcTemplate을 사용한 코드를 기록하였다.
[JdbcTemplateMemberRepository]
package myStudyspring.myStudyspring.repository;
import myStudyspring.myStudyspring.domain.member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class JdbcTemplateMemberRepository implements memberRepository{
private final JdbcTemplate jdbcTemplate;
@Autowired // 생략 가능
public JdbcTemplateMemberRepository(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public member save(member member) {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("member").usingGeneratedKeyColumns("id");
Map<String, Object> parameters = new HashMap<>();
parameters.put("name", member.getName());
Number key = jdbcInsert.executeAndReturnKey(new
MapSqlParameterSource(parameters));
member.setId(key.longValue());
return member;
}
@Override
public Optional<member> findById(Long id) {
List<member> result= jdbcTemplate.query("select * from member where id=?", memberRowMapper(), id);
return result.stream().findAny();
}
@Override
public Optional<member> findByName(String name) {
List<member> result= jdbcTemplate.query("select * from member where name=?", memberRowMapper(), name);
return result.stream().findAny();
}
@Override
public List<member> findAll() {
return jdbcTemplate.query("select * from member", memberRowMapper());
}
//여기서 개체 생성 후 넘어감.
private RowMapper<member> memberRowMapper(){
return (rs, rowNum) -> {
member member = new member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return member;
};
}
}
sql문은 jdbcTemplate.query()안에 직접 작성하고
결과는 RowMapper로 받는다.
변수가 필요한 경우 바인딩해준다.
RowMapper?
- 원하는 형태의 결과값을 반환할 수 있다.
- jdbc에서 ResultSet 결과를 직접 꺼내 객체에 저장하던 방식을 자동화해준다.
Jdbc Repository를 생성한 후 SpringConfig에서 스프링 빈으로 등록해야 하는데
JdbcTemplates은 DataSource를 필요로 한다.
Datasource는 데이터베이스 커넥션을 획득할 때 사용하는 객체이며, 스프링 부트는 데이터베이스 커넥션 정보를 바탕으로 DataSource를 생성하고 스프링 빈으로 만들어준다.
따라서 다음과 같이 DataSource를 주입받는다.
[SpringConfig]
package myStudyspring.myStudyspring;
//import myStudyspring.myStudyspring.repository.JdbcMemberRepository;
import myStudyspring.myStudyspring.repository.JdbcTemplateMemberRepository;
import myStudyspring.myStudyspring.repository.memberRepository;
//import myStudyspring.myStudyspring.repository.memoryMemberRepository;
import myStudyspring.myStudyspring.service.MemberService;
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 SpringConfig(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository()
);
}
@Bean
public memberRepository memberRepository(){
// return new memoryMemberRepository(); //메모리 저장소
// return new JdbcMemberRepository(dataSource); //순수 jdbc Repository
return new JdbcTemplateMemberRepository(dataSource); //jdbctemplate Repository
}
}
위의 코드를 보면 스프링의 장점을 알 수 있다.
메모리 저장소 구현체(memoryMemberRepository),
jdbc 구현체(JdbcMemberRepository),
jdbcTemplates 구현체(JdbcTemplateMemberRepository)
이렇게 3개의 구현체들이 생성되어 있는데 스프링의 DI를 사용하면 기존의 코드를 전혀 손대지 않고
SpringConfig의 설정만으로 구현 클래스를 어떤 것으로 할 것인지 변경할 수 있다.
즉 객체 지향 개발의 원칙 중 하나인 OCP의 원리를 확인할 수 있다.
* OCP(Open-Closed Principle) 개방-폐쇄 원칙 : 확장에는 열려있고 수정, 변경에는 닫혀있다.
정리해보면
데이터 베이스 설치 -> build.gradle과 application.properties 환경설정 -> jdbc Repository 생성
-> SpringConfig에서 스프링 빈으로 등록하기 위한 설정 변경
의 과정을 통해 스프링과 데이터베이스를 연동하였다.
이제 메모리 저장소가 아닌 데이터베이스를 연결하였기 때문에
서버를 종료하였다 다시 시작해도 데이터가 그대로 남아있다.
'컴퓨터 > Spring Boot' 카테고리의 다른 글
[TIL] Spring Boot(intellij) - [DB-4] JPA와 스프링 데이터 JPA (0) | 2023.06.07 |
---|---|
[TIL] Spring Boot(intellij) - [DB-3] DB 연결 테스트 (0) | 2023.06.02 |
[TIL] Spring Boot(intellij) - [DB-1] H2 데이터베이스 설치 (0) | 2023.06.01 |
[TIL] Spring Boot(intellij) - 홈 화면, 회원 등록, 조회 개발 (0) | 2023.05.30 |
[TIL] Spring Boot(intellij) - 스프링 빈과 의존 관계 (0) | 2023.05.27 |