[Spring] Spring에서 Query문 리팩토링(4)

배지원·2022년 10월 26일
0

실습

목록 보기
8/24
post-custom-banner

이전에 했던 프로젝트를 JdbcTemplate 리팩토링하여 기존의 코드를 좀 더 간단히 출력하고 최종 형식을 맞춘 JDBC 쿼리문을 만들어 보겠다.
이전 프로젝트 : https://velog.io/@qowl880/Spring-Spring%EC%97%90%EC%84%9C-Query%EB%AC%B8-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%813

1. JdbcTemplate

  • DAO객체에서 DB와 연동하기 위해 SQL 연산들을 수행 할 수 있도록 도와주는 기술이다
    스프링에서 JDBC를 이용하는 DAO에서 사용할수있도록 템플릿/콜백 기술을 제공한다
    생성자의 파라미터로 dataSource를 사용한다

  • JdbcTemplate이 JdbcContext를 완전히 대체 가능하며 JDBC를 매우 편하게 사용할 수 있다.

JdbcTemplate 구현

UserDao 생성자 초기화

private JdbcTemplate jdbcTemplate;

public UserDao(DataSource dataSource) {
   this.jdbcTemplate = new JdbcTemplate(dataSource);
}

deleteAll 메서드

public void deleteAll() throws SQLException {
    this.jdbcTemplate.update("delete from users");
}

add 메서드

public void add(final User user) throws SQLException {
    this.jdbcTemplate.update("insert into users(id, name, password) values (?, ?, ?);",
        user.getId(), user.getName(), user.getPassword());
}

update( )

  • executeSql( )과 기능이 비슷한 메서드
  • SQL연산을 통해 데이터베이스를 갱신시켜줄때(INSERT,DELETE,UPDATE)사용하는 메서드이다.


getCount 메서드

public int getCount() throws SQLException {
   return this.jdbcTemplate.queryForObject("select count(*) from users;", Integer.class);
}

queryforObject( )

  • SELECT를 실행했을 때 하나의 객체(Object) 결과 값이 나올 때 사용하는 메소드이다.
    • 결과로 단일 행을 받는 대신, 만약 0 또는 1 초과의 행이 반환 되면 에러를 발생 시킨다.
  • getCount()에 적용했던 RowMapper 콜백을 사용해줘야 한다.


findById 메서드

public User findById(String id) {
   String sql = "select * from users where id = ?";
   RowMapper<User> rowMapper = new RowMapper<User>() {
       @Override
       public User mapRow(ResultSet rs, int rowNum) throws SQLException {
           User user = new User(rs.getString("id"), rs.getString("name"),
                   rs.getString("password"));
           return user;
       }
   };
   return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
}

getAll 메서드

public List<User> getAll() {

   String sql = "select * from users order by id";
   RowMapper<User> rowMapper = new RowMapper<User>() {
       @Override
       public User mapRow(ResultSet rs, int rowNum) throws SQLException {
           User user = new User(rs.getString("id"), rs.getString("name"),
                   rs.getString("password"));
           return user; 
    }
   };
   return this.jdbcTemplate.query(sql, rowMapper);
}

RowMapper

  • 원하는 객체로 타입을 변환하는 역할이다.
  • queryForObject의 반환형은 데이터형만 가능 하지만, SELECT로 나온 여러개의 값을 반환 할 수 있을 뿐만 아니라, 사용자가 원하는 형태로도 얼마든지 받을 수 있다.



RowMapper의 중복 제거

  • findById 메서드와 getAll 메서드에서 RowMapper가 중복코드가 발생하였는데 이것을 메서드로 따로 빼서 중복코드를 없애준다
RowMapper<User> rowMapper = new RowMapper<User>() {
   @Override
   public User mapRow(ResultSet rs, int rowNum) throws SQLException {
       User user = new User(rs.getString("id"), rs.getString("name"),
               rs.getString("password"));
       return user;
   }
};


public User findById(String id) {
   String sql = "select * from users where id = ?";
   return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
}

public List<User> getAll() {
   String sql = "select * from users order by id";
   return this.jdbcTemplate.query(sql, rowMapper);
}

그동안 작성한 대표적인 부분 정리

클래스이름Context전략선택 전략사용 방법
UserDao.add(), .findById()ConnectionMakerAwsConnectionMaker
LocalConnectionMaker
TeacherConnectionMaker
중복코드 분리 및 DB별
구현체 필요에 따라 사용
FactoryawsConnection()UserFactoryawsConnectionConnectionMaker와 DAO를
연결시켜주는 역할,
필요한 ConnectionMaker를
추가시키기 위해서
Strategy.deleteAll()StatementStrategyDeleteAllStrategy
AddStrategy
SQL 쿼리문 별도 분리 interface를
의존하게하여 구현체를 필요에
따라 사용
DataSourceConnection ->
DataSource
DataSourceawsDataSourceConnection을 DataSource
인터페이스로 변경하였다.
따라서, ConnectionMaker는
더이상 필요하지 않다.
Factory클래스에 한번에 작성함
JdbcTemplateDAO 메서드 전부JdbcTemplateupdate()
queryforObject( )
RowMapper
자바 내에 있는 JdbcTemplate
인터페이스를 사용하여
Context -> JdbcTample로 사용
그동안 작성한 코드를 한줄로 사용


※ 코드 정리 : https://github.com/Bae-Ji-Won/Spring-Study/tree/main/git/Toby-spring-jdbc/src/main/java/dao/JdbcTemplate

profile
Web Developer
post-custom-banner

0개의 댓글