Bepoz
파즈의 공부 일기
Bepoz
전체 방문자
오늘
어제
  • 분류 전체보기 (232)
    • 공부 기록들 (85)
      • 우테코 (17)
    • Spring (85)
    • Java (43)
    • Infra (17)
    • 책 정리 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Bepoz

파즈의 공부 일기

공부 기록들/우테코

Spring JDBC 기초 사용법 정리

2021. 4. 22. 01:25

Spring JDBC 기초 사용법 정리

NamedParameterJdbcTemplate

@Repository
public class NamedParamDAO {
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    public NamedParamDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
        this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
    }

    /**
     * MapSqlParameterSource
     * public <T> T queryForObject(String sql, SqlParameterSource paramSource, Class<T> requiredType)
     */
    public int useMapSqlParameterSource(String firstName) {
        String sql = "select count(*) from customers where first_name = :first_name";

        SqlParameterSource namedParameters = new MapSqlParameterSource("first_name", firstName);

        return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
    }

    /**
     * BeanPropertySqlParameterSource
     * public <T> T queryForObject(String sql, SqlParameterSource paramSource, Class<T> requiredType)
     */
    public int useBeanPropertySqlParameterSource(Customer customer) {
        String sql = "select count(*) from customers where first_name = :firstName";

        SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(customer);

        return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
    }
}

:firstName 와 같이 두면 해당 값을 MapSqlParamewterSource(:다음에 적은 값) 을 통해 값을 넣어줄 수가 있다.
BeanPropertySqlParameterSource(객체) 를 이용하면 해당 객체 내부의 :적은 값을 해당 객체의 필드에서 뽑아와서 알 수가 있다.


Select 문

@Repository
public class QueryingDAO {
    private JdbcTemplate jdbcTemplate;

    public QueryingDAO(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    private final RowMapper<Customer> actorRowMapper = (resultSet, rowNum) -> {
        Customer customer = new Customer(
                resultSet.getLong("id"),
                resultSet.getString("first_name"),
                resultSet.getString("last_name")
        );
        return customer;
    };

    /**
     * public <T> T queryForObject(String sql, Class<T> requiredType)
     */
    public int count() {
        String sql = "select count(*) from customers";
        return jdbcTemplate.queryForObject(sql, Integer.class);
    }

    /**
     * public <T> T queryForObject(String sql, Class<T> requiredType, @Nullable Object... args)
     */
    public String getLastName(Long id) {
        String sql = "select last_name from customers where id = ?";
        return jdbcTemplate.queryForObject(sql, String.class, id);
    }

    /**
     * public <T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
     */
    public Customer findCustomerById(Long id) {
        String sql = "select id, first_name, last_name from customers where id = ?";
        return jdbcTemplate.queryForObject(
                sql,
                (resultSet, rowNum) -> {
                    Customer customer = new Customer(
                            resultSet.getLong("id"),
                            resultSet.getString("first_name"),
                            resultSet.getString("last_name")
                    );
                    return customer;
                }, id);
    }

    /**
     * public <T> List<T> query(String sql, RowMapper<T> rowMapper)
     */
    public List<Customer> findAllCustomers() {
        String sql = "select id, first_name, last_name from customers";
        return jdbcTemplate.query(
                sql,
                (resultSet, rowNum) -> {
                    Customer customer = new Customer(
                            resultSet.getLong("id"),
                            resultSet.getString("first_name"),
                            resultSet.getString("last_name")
                    );
                    return customer;
                });
    }

    /**
     * public <T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
     */
    public List<Customer> findCustomerByFirstName(String firstName) {
        String sql = "select id, first_name, last_name from customers where first_name = ?";
        return jdbcTemplate.query(sql, actorRowMapper, firstName);
    }
}

queryForObject는 결과 쿼리라인이 1개일 때 사용한다.
jdbcTemplate.queryForObject("select count(*) from customers", Integer.class); 에서는 결과값이 Integer 형태로 나오게되므로 Integer.class를 인수로 넣어주었다.

        String sql = "select last_name from customers where id = ?";
        return jdbcTemplate.queryForObject(sql, String.class, id);

위 경우에서도 결과가 String 타입이므로 String.class를 넣어준 것을 볼 수가 있다. ? 의 등장순서에 맞게끔 인수로 id를 넣어준 것도 확인할 수가 있다.

    public Customer findCustomerById(Long id) {
        String sql = "select id, first_name, last_name from customers where id = ?";
        return jdbcTemplate.queryForObject(
                sql,
                (resultSet, rowNum) -> {
                    Customer customer = new Customer(
                            resultSet.getLong("id"),
                            resultSet.getString("first_name"),
                            resultSet.getString("last_name")
                    );
                    return customer;
                }, id);
    }

위 코드에서는 여러 컬럼들이 나오게된다. 이를 resultSet.get타입("컬럼명")과 같이 사용해서 원하는 값을 뽑아올 수 있고, 예제처럼 객체를 생성해서 반환해줄 수도 있다.

    public List<Customer> findAllCustomers() {
        String sql = "select id, first_name, last_name from customers";
        return jdbcTemplate.query(
                sql,
                (resultSet, rowNum) -> {
                    Customer customer = new Customer(
                            resultSet.getLong("id"),
                            resultSet.getString("first_name"),
                            resultSet.getString("last_name")
                    );
                    return customer;
                });
    }

where 절을 사용하게되면 쿼리의 결과 수가 1이 아닌 다수가 나오게 되는데, query를 사용하게되면 List 형태로 뽑아올 수 있게 된다. 내부 컬럼을 뽑는 것은 이전 예제와 같다. 만약 first_name만 뽑아오고 싶다면 (resultSet, rowNum) -> resultSet.getString("first_name")와 같이 사용하면 된다.

    private final RowMapper<Customer> actorRowMapper = (resultSet, rowNum) -> {
        Customer customer = new Customer(
                resultSet.getLong("id"),
                resultSet.getString("first_name"),
                resultSet.getString("last_name")
        );
        return customer;
    };

다음과 같이 메서드로 따로 뽑아내는 것도 가능하다.


Insert 문, Delete 문, Update 문

@Repository
public class UpdatingDAO {
    private JdbcTemplate jdbcTemplate;

    public UpdatingDAO(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    private final RowMapper<Customer> actorRowMapper = (resultSet, rowNum) -> {
        Customer customer = new Customer(
                resultSet.getLong("id"),
                resultSet.getString("first_name"),
                resultSet.getString("last_name")
        );
        return customer;
    };

    /**
     * public int update(String sql, @Nullable Object... args)
     */
    public void insert(Customer customer) {
        String sql = "insert into customers (first_name, last_name) values (?, ?)";
        jdbcTemplate.update(sql, customer.getFirstName(), customer.getLastName());
    }
    /**
     * public int update(String sql, @Nullable Object... args)
     */
    public int delete(Long id) {
        String sql = "delete from customers where id = ?";
        return jdbcTemplate.update(sql, Long.valueOf(id));
    }

    /**
     * public int update(final PreparedStatementCreator psc, final KeyHolder generatedKeyHolder)
     */
    public Long insertWithKeyHolder(Customer customer) {
        String sql = "insert into customers (first_name, last_name) values (?, ?)";

        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(connection -> {
            PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
            ps.setString(1, customer.getFirstName());
            ps.setString(2, customer.getLastName());
            return ps;
        }, keyHolder);

        return keyHolder.getKey().longValue();
    }
}

jdbcTemplate.update()를 사용하면 Insert, Delete, Update 문을 처리할 수가 있다.
insert를 실행한 후에 해당 id 값을 바로 얻을 수 있는 방법이 있다.

    public Long insertWithKeyHolder(Customer customer) {
        String sql = "insert into customers (first_name, last_name) values (?, ?)";

        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(connection -> {
            PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
            ps.setString(1, customer.getFirstName());
            ps.setString(2, customer.getLastName());
            return ps;
        }, keyHolder);

        return keyHolder.getKey().longValue();
    }

뽑아내고자 하는 값을 new String[] {"id"} 로 뽑아서 바로 리턴하는 것을 확인할 수가 있다.


SimpleJdbcInsert

@Repository
public class SimpleInsertDao {
    private SimpleJdbcInsert insertActor;

    public SimpleInsertDao(DataSource dataSource) {
        this.insertActor = new SimpleJdbcInsert(dataSource)
                .withTableName("customers")
                .usingGeneratedKeyColumns("id");
    }

    /**
     * Map +
     * insertActor.executeAndReturnKey
     */
    public Customer insertWithMap(Customer customer) {
        Map<String, Object> parameters = new HashMap<String, Object>(3);
        parameters.put("first_name", customer.getFirstName());
        parameters.put("last_name", customer.getLastName());
        Long id = insertActor.executeAndReturnKey(parameters).longValue();
        return new Customer(id, customer.getFirstName(), customer.getLastName());
    }

    /**
     * SqlParameterSource +
     * insertActor.executeAndReturnKey
     */
    public Customer insertWithBeanPropertySqlParameterSource(Customer customer) {
        SqlParameterSource parameters = new BeanPropertySqlParameterSource(customer);
        Long id = insertActor.executeAndReturnKey(parameters).longValue();
        return new Customer(id, customer.getFirstName(), customer.getLastName());
    }
}

키 값을 바로 빼내는 방법으로 추가적으로 위와 같은 코드를 이용할 수도 있다.


'공부 기록들 > 우테코' 카테고리의 다른 글

Spring MVC Config 기초 정리  (0) 2021.04.25
Spring CORE 기초 정리  (0) 2021.04.23
Spring MVC 기초 정리  (0) 2021.04.15
우아한 테크코스 한 달 생활기  (1) 2021.04.09
[모던 자바 인 액션 스터디] 8장 컬렉션 API 개선  (0) 2021.03.28
    '공부 기록들/우테코' 카테고리의 다른 글
    • Spring MVC Config 기초 정리
    • Spring CORE 기초 정리
    • Spring MVC 기초 정리
    • 우아한 테크코스 한 달 생활기
    Bepoz
    Bepoz
    https://github.com/Be-poz/TIL

    티스토리툴바