ACHO.pk devlog

[Springboot] 스프링 JdbcTemplate 본문

프레임워크/Springboot

[Springboot] 스프링 JdbcTemplate

Acho 2023. 1. 25. 20:52

인프런 김영한 강사님의 "스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술"의 강의를 듣고 학습하였습니다.


순수 Jdbc와 동일한 환경설정을 하면 된다.  (build.gradle 설정)

스프링 JdbcTemplate과 MyBatis 같은 라이브러리는 JDBC API에서 본 반복 코드를 대부분 제거해준다. 하지만 SQL은 직접 작성해야 한다.

 


스프링 JdbcTemplate 회원 레포지토리

ⓛ main/java/repository/패키지 하위에 "JdbcTemplateMemberRepository" 클래스를 만들어준다.

 

 

 

JdbcTemplateMemberRepository 클래스 내에 코드를 작성한다.

implements MemberRepository를 하고 난 후 빨간 밑줄이 생긴다. alt + enter로 Implement methods를 클릭해주면 필요한 코드를 자동 생성해준다.

package Springboot.study.repository;

import Springboot.study.domain.Member;
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;
    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 List<Member> findAll() {
        return jdbcTemplate.query("select * from member", memberRowMapper());
    }
    @Override
    public Optional<Member> findByName(String name) {
        List<Member> result = jdbcTemplate.query("select * from member where name = ?", memberRowMapper(), name);
        return result.stream().findAny();
    }
    private RowMapper<Member> memberRowMapper() {
        return (rs, rowNum) -> {
            Member member = new Member();
            member.setId(rs.getLong("id"));
            member.setName(rs.getString("name"));
            return member;
        };
    }
}

중요한 코드를 살펴보자.

 


public JdbcTemplateMemberRepository(DataSource dataSource) {
    jdbcTemplate = new JdbcTemplate(dataSource);
}

JdbcTemplate 사용시 DataSource가 필요하며, 이를 스프링 컨테이너에게 인잭션받기 위해 매개변수로 받아온다.

생성자가 하나인 경우에, 스프링 빈으로 등록되면 @Autowired 어노테이션을 생략할 수 있다.

스프링이 자동으로 dataSource를 인잭션해준다.

 


@Override
public Optional<Member> findById(Long id) {
    List<Member> result = jdbcTemplate.query("select * from member where id = ?", memberRowMapper(), id);
    return result.stream().findAny();
}

jdbcTemplate.query("쿼리문", RowMapper<?>, 바인딩할 파라미터 값) 과 같이 사용하면 된다.

RowMapper()는 결과값을 매핑하는 것이다. 

result 값을 stream으로 변환해서 하나라도 있으면 반환한다.

 

private RowMapper<Member> memberRowMapper() {
    return (rs, rowNum) -> {
        Member member = new Member();
        member.setId(rs.getLong("id"));
        member.setName(rs.getString("name"));
        return member;
    };
}

rs(ResultSet)이 값을 가져오고,  rowNum만큼 반복해서 member 객체에 id와 name를 설정해준다. 

rs로 결과를 받아서 member에 매핑해서 member를 반환한다.

 

//alt + Anter로 아래 코드를 람다식으로 바꿀 수 있다.

return new RowMapper<Member>() {
                @Override
                public Member mapRow(ResultSet rs, int rowNum) throws SQLException {
                    Member member = new Member();
                    member.setId(rs.getLong("id"));
                    member.setName(rs.getString("name"));
                    return member;

                }
            };

 

@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;
}

SimpleJdbcInsert은 알아서 insert문을 만들어준다.

테이블명은 member이고, 키 컬럼은 id이다.

parameters는 Map 타입으로 각 값들을 put해준다.

 


@Override
public List<Member> findAll() {
    return jdbcTemplate.query("select * from member", memberRowMapper());
}

memberRowMapper는 member객체를 반환하므로 그대로 씀

해당 쿼리 결과를 memberRowMapper()가 매핑해준다.


@Override
public Optional<Member> findByName(String name) {
    List<Member> result = jdbcTemplate.query("select * from member where name = ?", memberRowMapper(), name);
    return result.stream().findAny();
}

Member객체들의 List이므로 List<Member>라고 사용

 

 

 

 

③ SpringConfig 클래스 내에 코드를 작성한다.

package Springboot.study;

import Springboot.study.repository.JdbcTemplateMemberRepository;
import Springboot.study.repository.MemberRepository;
import Springboot.study.repository.MemoryMemberRepository;
import Springboot.study.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class SpringConfig {

    private final DataSource dataSource;
    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);
        return new JdbcTemplateMemberRepository(dataSource);
    }
}

 

 

 

 

'프레임워크 > Springboot' 카테고리의 다른 글

[Springboot] 스프링데이터 JPA  (0) 2023.01.26
[Springboot] JPA  (0) 2023.01.25
[Springboot] 스프링 통합 테스트  (0) 2023.01.24
[Springboot] 순수 JDBC  (0) 2023.01.23
[Springboot] H2 데이터베이스 설치  (0) 2023.01.22
Comments