SpringFramework/SpringBoot 기초

[SpringBoot] 스프링 DB 접근 기술

쭈봉이 2021. 12. 11. 01:16

1. H2 데이터베이스 설치(https://www.h2database.com/html/main.html)

 

h2 데이터베이스 설치 후 설치 폴더 > bin > h2.bat를 실행하면 db를 조작할수있는 화면이 뜬다

Table을 생성하고 간단하게 데이터를 몇개 삽입

create table member (
    id bigint generated by default as identity,
    name varchar(255),
    primary key(id)
)

insert into member(name) values ('spring');

select * from member;

2. DataBase 세팅

resource/application.properties에 db 정보를 입력한다.

spring.datasource.url = jdbc:h2:tcp://localhost/~/test
spring.datasource.username=sa
spring.datasource.driver-class-name = org.h2.Driver

이 연결정보를 스프링으로부터 주입받아야함

3. 스프링 JdbcTemplate

스프링 JdbcTemplate를 사용하면 반복적인 코드를 제거해준다.

SpringConfig에 빈을 등록할때 Repository를 지정함으로써 원하는 어떤 데이터베이스를 주입시킬지 결정할 수 있다.

import hello.hellospring.repository.JdbcMemberRepository;
import hello.hellospring.repository.JdbcTemplateMemberRepository;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.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 JdbcTemplateMemberRepository(dataSource);
    }
}
package hello.hellospring.repository;

import hello.hellospring.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.sql.ResultSet;
import java.sql.SQLException;
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;

    //Datasource 자동으로 인젝션
    @Autowired  // 생성자가 1개일 경우 @Autowired는 생략 가능
    public JdbcTemplateMemberRepository(DataSource dataSource){
        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 where name = ?",memberRowMapper());
    }

    private RowMapper<Member> memberRowMapper(){
        return (rs, rowNum) -> {

            Member member = new Member();
            member.setId(rs.getLong("id"));
            member.setName(rs.getString("name"));
            return member;
        };
    }

}