Spring
[Spring/DB] JDBC, SQL Mapper(JdbcTemplate, MyBatis), ORM(JPA - Hybernate): 차이점과 등장 배경, 장단점에 대하여
깃짱
2023. 6. 16. 14:43
반응형
💋 JDBC
- JDBC(Java Database Connectivity)
- JDBC는 데이터베이스에 접근하는 기능의 표준화로 개발자들이 데이터베이스를 종류별로 공부해야 하고, 데이터베이스 종류에 따라서 비즈니스 코드를 수정해야 하는 문제를 해결했다.
- 크게 기능을 구분하면, 데이터베이스에 커넥션 연결하기, SQL 매핑하기, 결과 응답 처리하기 세 가지로 나눌 수 있다.
- JDBC를 직접 사용해본 사람이라면 각 기능을 아래와 같이 연결해서 생각하면 편할 것 같다.
- 데이터베이스에 커넥션 연결: DriverManager.getConnection()
- SQL Mapping하기: PreparedStatement.setString(1, "아아악")
- 결과 응답 처리하기: ResultSet.next(), ResultSet.getString("member_id")
- 표준화를 이루었다는 것 만으로도 편리하긴 하지만, 가장 low level에서 동작하기 때문에 커넥션을 직접 연결하고 순차적으로 끊어주는 코드를 작성해야 하고, 과정에서 예외 발생 시 생기는 리소스 누수까지 고려해야 하는 등 귀찮은 일이 많았다. (지금은 신경쓸 필요 없는 일이다)
위의 내용을 다시 정리하면, JDBC의 정의와 효과는 아래와 같이 정리할 수 있을 것 같다.
- 자바에서 데이터베이스에 접속할 수 있도록 도와주는 API
- 데이터를 쿼리하거나, 업데이트하는 방법의 표준을 인터페이스로 제공한다.
- 개발자는 이 '표준' 인터페이스만 사용해서 개발하면 되고, 각 데이터베이스 별 커넥션, SQL 전달, 결과 응답 처리 방법에 대해서는 공부하지 않아도 되게 되었다.
- 각 DB 회사는 JDBC 인터페이스를 구현한 JDBC 드라이버를 제공한다. 각 DB의 특성에 따라 JDBC를 구현한 것이다.
아래 코드는 JDBC를 사용해서 데이터베이스에서 id에 따른 객체를 얻기 위해서 직접 커넥션을 얻고, sql을 매핑하고, 결과를 처리하는 과정이다. (쓰고싶지 않게 생김)
public Member findById(final String memberId) throws SQLException {
final String sql = "SELECT * FROM member WHERE member_id = ?";
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = getConnection();
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, memberId);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
final Member member = new Member();
member.setMemberId(resultSet.getString("member_id"));
member.setMoney(resultSet.getInt("money"));
return member;
} else {
throw new NoSuchElementException("membern ot found memberId=" + memberId);
}
} catch (SQLException e) {
log.error("db error", e);
throw e;
} finally {
close(connection, preparedStatement, resultSet);
}
}
private void close(final Connection connection, final Statement statement, final ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
log.error("error", e);
}
}
try {
statement.close();
} catch (SQLException e) {
log.info("error", e);
}
try {
connection.close();
} catch (SQLException e) {
log.info("error", e);
}
}
💋 SQL Mapper
JDBC의 사용을 편리하게 하기 위해서 등장한 기술이다.
- 종류로는 Spring에서 제공하는 JdbcTemplate, MyBatis 등이 있다.
- JDBC를 직접 사용하는 대신 개발자는 sql문만 작성하면 SQL Mapper가 커넥션 연결, SQL Mapping, 결과 응답 처리를 대신 해준다.
- 커넥션 연결 및 해제 등등 JDBC 코드에서 반복적으로 사용되는 부분을 제거해준다.
- SQL만 사용할 수 있다면 금방 배워서 사용할 수 있다.
- 단점도 있는데, 데이터베이스 별로 공통적인 sql에 대한 처리만 가능하고, 일부 각 데이터베이스의 특이한 부분은 직접 관리해야 한다.
public void updateMember(MemberEntity memberEntity) {
String sql = "UPDATE member SET email = ?, password = ? WHERE id = ?";
jdbcTemplate.update(sql, memberEntity.getEmail(), memberEntity.getPassword(), memberEntity.getId());
}
💋 ORM 기술 (JPA)
- Object Relational Mapping의 약자로, 객체 - 관계(데이터베이스) 매핑이라는 뜻이다.
- ORM을 사용하면 SQL마저 작성하지 않아도 된다.
- JPA는 인터페이스로, 구현체로는 하이버네이트, 이클립스링크 등이 있다.
- JPA 인터페이스를 사용하면 개발자는 직접 JDBC를 사용하는 대신, 자바 객체를 JPA에 전달하는 것 만으로도, JPA가 커넥션 관리, SQL 매핑, 결과 응답 처리를 JDBC를 접근해 대신 해주기 때문에, 데이터베이스에 CRUD할 수 있다.
- 자바 객체로 직접 List나 Map을 사용하는 것처럼 이해하면 이해하기 쉬울 것 같다.
- SQL문도 작성하지 않아도 되기 때문에 생산성이 매우 높아진다.
- 위에서 설명한 두 기술에 비해서 굉장히 간편하지만, 많이 추상화되어 있기 때문에 기본적인 내용에 대한 학습이 없다면 이해하기 어렵다. 앞서 등장한 두 가지부터 하면 좋을듯!
반응형