
spring-mvc 과제가 끝나고, 이번주 과제는 jdbc-1과 core-1,2이다.
jdbc에 대해 알아보자!!
데이터베이스 연결을 도와주는 JAVA의 API이다.
Jdbc가 있기 전에는 애플리케이션 서버가 DB와 직접 커넥션 연결하고, sql 날리고 했었다.
하지만, 여기엔 2가지 문제가 있었다.
1. DB가 바뀌면, 애플리케이션 서버의 코드도 바뀌어야한다.
2. DB가 바뀌면, 개발자가 새 DB 사용을 위한 지식을 새로 배워야한다.
그래서, 이를 해결하기 위해 Jdbc가 탄생했다.
Jdbc는 Java Database Connectivity의 약자로, db 연결을 위한 표준 인터페이스이다. 개발자는 db에 상관없이 Jdbc만 사용해서 개발하면 된다. 각 DB회사는 Jdbc 인터페이스를 구현하게 되고, 이를 'JDBC 드라이버'라고 한다.

public Member save(Member member) {
String sql = "insert into member(name) values(?)";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DataSourceUtils.getConnection(dataSource);;
pstmt = conn.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, member.getName());
pstmt.executeUpdate();
rs = pstmt.getGeneratedKeys();
if (rs.next()) {
member.setId(rs.getLong(1));
} else {
throw new SQLException("id 조회 실패");
}
return member;
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs);
}
}
DataSourceUtils.getConnection(dataSource)?로 비워두고, 파라미터 바인딩 방식을 통해 따로 넣어준다. 그런 Statement를 PreparedStatement라고 한다.close(..)finally를 통해 자원들을 무조건 close 해주어야 한다!위 코드를 보면 알 수 있다시피, 코드가 매우 복잡하고, 메인 로직보다 DB연결을 위한 코드가 많다. 이 문제를 해결하기 위해 JdbcTemplate가 등장한다.
Jdbc를 편하게 사용하기 위해, Spring이 제공하는 모듈이며, SQL Mapper이다. 따라서, 사용자는 sql만 사용할 줄 알면, 나머지 번거로운 일은 SQL Mapper가 대신 해준다.
public void insert(Customer customer) {
String sql = "insert into customers (first_name, last_name) values (?, ?)";
jdbcTemplate.update(sql, customer.getFirstName(), customer.getLastName());
}
try-catch, DB 커넥션을 위한 코드가 모두 사라져서, 사용자는 SQL 작성에만 집중할 수 있다.
트랜젝션 관리가 편하다!
Jdbc에서는 트랜젝션을 시작하기 위해서, 아래 코드가 필요했다.
connection.setAutoCommit(false);
connection.commit();
하지만, JdbcTemplate에서는 @Transactional을 통한, 트랜젝션 관리가 가능하다.
rs.next()를 반복해, 객체에 매핑 시켜주어야한다. 단일 객체가 아니면, while을 통해 반복해야해서, 불편하고, 실수할 가능성이 높아진다.RowMapper를 통해 편하게 객체 매핑을 할 수 있다.List<Person> persons = jdbcTemplate.query("select * from mytable where id=1",
(resultSet, i) -> new Person(
resultSet.getInt("id"),
resultSet.getString("name")
));
}
쿼리 시, 자동 생성되는 키 값을 받기 위해 사용한다.
일반적으로 삽입(insert) 작업 시, 자동 생성되는 키 값을 받기 위해 사용한다고 한다.
효율적으로 키 값을 받아올 수 있다고 하는데, 내가 보기엔 너무 복잡해 보인다.
public Number insertAndGetId(String value1, String value2) {
String sql = "INSERT INTO my_table (column1, column2) VALUES (?, ?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(
connection -> {
PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, value1);
ps.setString(2, value2);
return ps;
},
keyHolder
);
return keyHolder.getKey(); // 생성된 키를 반환
}