Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Jdbc Template으로 쉽게 DB 활용하기

Table of contents

  1. Jdbc Template 란?
  2. Jdbc Template 사용
    1. jdbcTemplate.update()
    2. jdbcTemplate.queryForObject()
    3. jdbcTemplate.query()

Jdbc Template 란?


스프링은 JDBC를 위한 다양한 메서드를 제공하고 있으며, JdbcTemplate 클래스를 생성하면 된다.

파라미터로는 DataSource 를 입력해주면 된다.


Jdbc Template 사용


@Configuration
public class UserDaoConfig {

    @Bean
    public UserDao userDao() {
        return new UserDao(dataSource());
    }

    @Bean
    public DataSource dataSource() {
        Map<String, String> env = System.getenv();

        SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriverClass(com.mysql.cj.jdbc.Driver.class);
        dataSource.setUrl(env.get("DB_HOST"));
        dataSource.setUsername(env.get("DB_USER"));
        dataSource.setPassword(env.get("DB_PASSWORD"));
        return dataSource;
    }


}

위와 같은, DataSource 객체를 Configuration 에너테이션이 있는 소스파일안에서 스프링 빈 저장소에 의해 입력받게 될 것이다.

JdbcTemplate 를 사용하고 싶은 파일에서는,

public class UserDao {

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

DI 주입에 의해 입력된 dataSource 는 기본 생성자에서 JdbcTemplate 의 매개변수로 입력되고, JdbcTemplate 객체가 초기화 되어, 다양한 메서드를 사용할 수 있다.

jdbcTemplate.update()


public class UserDao {

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

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

jdbcTemplate 를 사용했더니, 엄청나게 간결해졌다.

jdbcTemplate.update 메서드는, 위와 같이 ResultSet 이 없는, MYSQL 에 쿼리문만 전달 시켜서 실행시키는 구문을 실행시킬 때 사용하면 된다.

update("SQL 쿼리문", 쿼리문에 바인딩 할 시 파라미터 )

jdbcTemplate.queryForObject()


public class UserDao {
    
    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 int getCount() throws SQLException, ClassNotFoundException {
        String sql = "SELECT COUNT(*) AS COUNT FROM USERS";
        return this.jdbcTemplate.queryForObject(sql, Integer.class);
    }

    public User getById(String id) throws SQLException, ClassNotFoundException {
        String sql = "SELECT * FROM USERS WHERE ID = ?";
        return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
    }
}

queryForObject 는 SQL 쿼리문 실행 결과로 부터 원하는 데이터를 추출할 수 있다.

기본 사용 방법은 queryForObject(SQL 구문, 반환타입, 바인딩 할 시 파라미터) 이다.

예를 들면, jdbcTemplate.queryForObject("SELECT password FROM USERS WHERE id = ?",String.class,"1234") 라고 하면, id가 “1234” 인 유저의 패스워드를 String 타입으로 반환받겠다는 의미이다.

따라서, getCount() 메서드에서는 queryForObject(sql,Integer.class) 로 사용하였고, 이는 quertForInt(sql) 로 사용할 수 도 있다.


getById() 메서드에서는 SQL 결과물 정보를 USER 객체에 인스턴스 변수에 각각 저장한 뒤, 객체를 반환하기 위해서 rowMapper 라는 것을 사용하였다.

RowMapper 는 SQL 결과물 테이블에서 행 하나를 맵핑한다고 생각하면 된다. RowMapper 는 인터페이스이기 때문에, @Override 에너테이션이 있는 mapRow() 메서드를 원하는 방식으로 오버라이딩 해주어야 한다. 쿼리문의 결과로 생성되는 ResultSet 객체에서 getString("속성명") 을 통해서 User 객체의 인스턴스에 데이터를 저장한 후 User 를 반환하게 구현하면 된다.

jdbcTemplate.query()


query() 메서드는 ResultSet 의 모든 로우를 열람하면서, 로우마다 rowMapper 로 구현한 mapRow 메서드를 사용한다. 따라서, DB에서 가져오는 로우의 개수만큼 호출될 것이다. 그리고, 이러한 결과를 List 객체에 담아서 반환해준다.

public class UserDao {
    
    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 List<User> getAll(){
        String sql = "SELECT * FROM USERS ORDER BY id";
        return this.jdbcTemplate.query(sql, rowMapper);
    }
}

위와 같은 코드를 실행시키면, 쿼리문 실행 결과를 바탕으로 한 데이터를 User 객체에 담은 뒤, 그 User 객체들을 담고 있는 List 객체가 반환되어 .size().get() 과 같은 List 메서드를 활용하여 데이터를 다룰 수 있게 된다.