[Spring๐ฑ] JDBC,Spring JDBC,Spring JPA ๊ฐ๋ ๊ณผ ์ฌ์ฉ๋ฒ ์ด์ ๋ฆฌ
/ 9 min read
Table of Contents
JDBC, Spring JDBC, Spring JPA ๊ฐ๋ ๊ณผ ์ฌ์ฉ๋ฒ ์ด์ ๋ฆฌ
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ์์ฉํ๋ ๋ฐฉ์์ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์๋ค. JDBC๋ก ์์ํด, ์ด๋ฅผ ์ถ์ํํ Spring JDBC, ๊ทธ๋ฆฌ๊ณ ORM ๊ธฐ๋ฐ์ Spring JPA(Hibernate)๊น์ง ๋ค์ํ ๊ณ์ธต์ ์ ๊ทผ ๋ฐฉ๋ฒ์ด ์กด์ฌํ๋ค. ์ด๋ฒ ํฌ์คํ ์์๋ ์ด ์ธ ๊ฐ์ง ๊ธฐ์ ์ ํน์ง๊ณผ ์ฌ์ฉ๋ฒ์ ๊ฐ๋ตํ ์ดํด๋ณด๊ณ , ์์ ์ฝ๋๋ฅผ ํตํด ์ฐจ์ด์ ์ ๋น๊ตํด๋ณธ๋ค.
CommandLineRunner์ ApplicationRunner
Spring Boot ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ๋ํ ๋, ํน์ ๋ก์ง์ ์๋์ผ๋ก ์คํํ๊ณ ์ถ๋ค๋ฉด CommandLineRunner
๋๋ ApplicationRunner
์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
@Componentpublic class CourseJdbcCommandLineRunner implements CommandLineRunner {
@Autowired private CourseJdbcRepository repository;
@Override public void run(String... args) throws Exception { repository.insert(); }}
- CommandLineRunner: ์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์
์ด ๊ฐ๋๋ ์งํ
run(String... args)
๋ฉ์๋๋ฅผ ์คํํ๋ค. - ApplicationRunner:
CommandLineRunner
์ ์ ์ฌํ์ง๋ง,run(ApplicationArguments args)
ํํ๋ก ์ธ์๋ฅผ ์ ๋ฌ๋ฐ๋๋ค.
๋ ์ค ํ๋๋ฅผ ์ ํํด ๊ฐ๋ฐ ํ๊ฒฝ ๋ฐ ํ์์ ๋ฐ๋ผ ์ฌ์ฉํ ์ ์๋ค.
JDBC
**JDBC (Java Database Connectivity)**๋ ์๋ฐ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐํ๊ณ SQL ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ธฐ ์ํ ํ์ค ์ธํฐํ์ด์ค์ด๋ค. ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ด๋ฉฐ, ๋ชจ๋ DB ์์ ์ ์ง์ ์ฒ๋ฆฌํ๋ค.
์๋ ์์๋ ๋จ์ํ ์ญ์ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ์ํํ๋ ๋ชจ์ต์ด๋ค.
public void deleteTodo(int id) { PreparedStatement st = null; try { st = db.conn.prepareStatement("delete from todo where id=?"); st.setInt(1, id); st.execute(); } catch (SQLException e) { logger.fatal("Query Failed : ", e); } finally { if (st != null) { try { st.close(); } catch (SQLException e) {} } }}
JDBC์ ํน์ง
- ์ง์ ์ ์ธ SQL ์์ฑ: SQL ์ฟผ๋ฆฌ๋ฌธ์ ์ง์ ๊ด๋ฆฌํ๋ค.
- ์์ธํ ์์ธ ์ฒ๋ฆฌ ๋ฐ ์์ ๊ด๋ฆฌ ํ์:
try-catch-finally
๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ปค๋ฅ์ , ์คํ ์ดํธ๋จผํธ, ๋ฆฌ์์ค ํด์ ๋ฑ์ ์ง์ ์ฒ๋ฆฌํด์ผ ํ๋ค. - ์ ์ฐ์ฑ ๋์: ์ํ๋ ๋๋ก SQL ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ์ปค์คํฐ๋ง์ด์งํ ์ ์๋ค.
Spring JDBC
Spring JDBC๋ JDBC๋ฅผ ๋์ฑ ๊ฐ๋จํ ์ฌ์ฉํ ์ ์๋๋ก ๋์์ฃผ๋ ์ถ์ํ ๊ณ์ธต์ด๋ค. JdbcTemplate
ํด๋์ค๋ฅผ ํตํด ๋ฐ๋ณต์ ์ธ ์ฝ๋(์ฐ๊ฒฐ, ์์ธ ์ฒ๋ฆฌ ๋ฑ)๋ฅผ ์ ๊ฑฐํ๊ณ , SQL ์คํ ๋ก์ง์ ๊ฐ๋จํ ์์ฑํ ์ ์๊ฒ ํด์ค๋ค.
@Repositorypublic class CourseJdbcRepository {
@Autowired private JdbcTemplate springJdbcTemplate;
private static final String INSERT_QUERY = """ insert into course (id,name,author) values(2, 'azure', 'solo'); """;
public void insert() { springJdbcTemplate.update(INSERT_QUERY); }}
- JdbcTemplate: SQL ์คํ(
update
,queryForObject
๋ฑ)์ ๊ฐ๋จํ ์ํํ ์ ์๋๋ก ํด์ค๋ค. - ์ฝ๋ ๊ฐ๊ฒฐํ: ๊ธฐ์กด JDBC๋ณด๋ค ์์ ๊ด๋ฆฌ์ ์์ธ ์ฒ๋ฆฌ๊ฐ ์๋ํ๋์ด ์๋ค.
JdbcTemplate๊ณผ queryForObject() ํ์ฉ
insert, delete ์์
@Repositorypublic class CourseJdbcRepository {
private static final String INSERT_QUERY = """ insert into course (id, name, author) values(?, ?, ?); """;
private static final String DELETE_QUERY = """ delete from course where id = ? """;
@Autowired private JdbcTemplate springJdbcTemplate;
public void insert(Course course) { springJdbcTemplate.update(INSERT_QUERY, course.getId(), course.getName(), course.getAuthor()); }
public void deleteById(long id) { springJdbcTemplate.update(DELETE_QUERY, id); }}
update()
: INSERT, DELETE, UPDATE ๋ฑ ์ฟผ๋ฆฌ๋ฅผ ์คํํ ๋ ์ฌ์ฉํ๋ค. ์คํ๋ ํ(row)์ ๊ฐ์๋ฅผ ๋ฐํํ๋ค.
queryForObject()
์ RowMapper
๋จ์ผ ๋ ์ฝ๋๋ฅผ ์กฐํํ ๋ ์ฃผ๋ก ์ฌ์ฉํ๋ ๋ฉ์๋์ด๋ค. ์๋ฅผ ๋ค์ด, ํน์ id
๋ก Course ๊ฐ์ฒด๋ฅผ ์กฐํํ๋ค๊ณ ๊ฐ์ ํ์.
public Course findById(long id) { String sql = "SELECT * FROM course WHERE id = ?"; return springJdbcTemplate.queryForObject( sql, new BeanPropertyRowMapper<>(Course.class), id );}
queryForObject()
: ์ฒซ ๋ฒ์งธ ์ธ์๋ก SQL ์ฟผ๋ฆฌ, ๋ ๋ฒ์งธ ์ธ์๋กRowMapper
, ์ธ ๋ฒ์งธ ์ธ์๋ก ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ๋๋ค.- BeanPropertyRowMapper: SQL ๊ฒฐ๊ณผ๋ฅผ Java ๊ฐ์ฒด์ ํ๋กํผํฐ์ ์๋ ๋งคํํด์ค๋ค. ํ๋ ์ด๋ฆ๊ณผ ์ปฌ๋ผ ์ด๋ฆ์ด ์ผ์นํ๋ฉด ์๋์ผ๋ก ํ ๋นํ๋ค.
RowMapper์ ์๋ ์๋ฆฌ
- SQL ์คํ ๊ฒฐ๊ณผ์ธ
ResultSet
์ ๋ฐ๋๋ค. RowMapper
๊ตฌํ์ฒด๊ฐResultSet
์ ๊ฐ ์ปฌ๋ผ์ Java ๊ฐ์ฒด๋ก ๋งคํํ๋ค.- ๋งคํ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
Spring JPA์ Hibernate
**JPA (Java Persistence API)**๋ ์๋ฐ ์ง์์์ ์ ์ํ ORM(Object-Relational Mapping) ํ์ค ์ธํฐํ์ด์ค์ด๋ค. Hibernate๋ ์ด JPA ํ์ค์ ๋ํ์ ์ธ ๊ตฌํ์ฒด์ด๋ค.
- JPA: ์ด๋ค ๊ธฐ๋ฅ(๋ฉ์๋, API)์ ๊ฐ์ ธ์ผ ํ๋์ง ๋ช ์ธํ ์ธํฐํ์ด์ค(ํ์ค).
- Hibernate: JPA ๊ท๊ฒฉ์ ๊ตฌํํ ์ค์ ๊ตฌํ์ฒด.
์๋ฅผ ๋ค์ด,@Entity
,@Table
,@Id
๋ฑ ์ ๋ํ ์ด์ ๊ธฐ๋ฐ์ผ๋ก DB ํ ์ด๋ธ๊ณผ Java ๊ฐ์ฒด๋ฅผ ๋งคํํด์ค๋ค.
JPA ์ฌ์ฉ ์ ์ฅ์
- ์์ฐ์ฑ: ์ง์ SQL์ ์์ฑํ์ง ์์๋, ๋ฉ์๋ ์ด๋ฆ์ด๋ JPA ์ฟผ๋ฆฌ(
JPQL
)๋ก ์ฝ๊ฒ CRUD๋ฅผ ๊ตฌํํ ์ ์๋ค. - ๊ฐ์ฒด ์งํฅ์ ๋ฐ์ดํฐ ์ ๊ทผ: ํด๋์ค์ ํ๋๋ง ์ ์ํด๋๋ฉด, JPA๊ฐ ํ ์ด๋ธ๊ณผ ์๋์ผ๋ก ๋งคํํด์ค๋ค.
- ํธ๋์ญ์ ๋ฐ ์บ์ฑ: ์์์ฑ ์ปจํ ์คํธ, 1์ฐจ ์บ์, ์ง์ฐ ๋ก๋ฉ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ผ๋ก ๊ฐ๋ฐ ์์ฐ์ฑ๊ณผ ์ฑ๋ฅ์ ๋์ธ๋ค.
์ ์ง์ Hibernate๋ฅผ ์ฌ์ฉํ์ง ์๊ณ JPA ์ฝ๋๋ฅผ ์ฐ๋?
- ๊ตฌํ์ฒด ๊ต์ฒด ์ ์ฐ์ฑ: Hibernate ์ธ์๋ EclipseLink, OpenJPA ๋ฑ์ด ์๋ค. JPA ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ธ์ ๋ ๋ค๋ฅธ ๊ตฌํ์ฒด๋ก ๊ฐ์ํ ์ ์๋ค.
- ํ์คํ: JPA๋ ์๋ฐ ์ง์์์ ํ์ค์ผ๋ก ์ธ์ ๋ฐ์ ์คํ์ด๋ฏ๋ก, ์ผ๊ด๋ ์ฝ๋๋ฅผ ์ ์งํ ์ ์๋ค.
JDBC vs Spring JDBC vs Spring JPA ๋น๊ต
1) JDBC
- ์ง์ SQL ์์ฑ: ์์ ๋๊ฐ ๋งค์ฐ ๋์ง๋ง, ๋ฐ๋ณต ์ฝ๋๊ฐ ๋ง๋ค.
- ์์ธ ์ฒ๋ฆฌ์ ์์ ๊ด๋ฆฌ: ๊ฐ๋ฐ์๊ฐ ์ธ์ธํ๊ฒ ์ ์ดํด์ผ ํจ.
- ํ์ต ๊ณก์ : ์ฝ์ง๋ง, ๋๊ท๋ชจ ํ๋ก์ ํธ์์๋ ์ ์ง๋ณด์์ฑ์ด ๋จ์ด์ง ์ ์๋ค.
2) Spring JDBC
JdbcTemplate
: ๋ฐ๋ณต์ ์ธ DB ์ ๊ทผ ๋ก์ง์ ์ถ์ํํด ์ฝ๋ ๊ฐ๊ฒฐํ.- ์์ธ ๋ณํ: SQL ์์ธ๋ฅผ Spring ์์ธ๋ก ๋ณํํด ์ผ๊ด๋ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅ.
- ์ ์ ํ ์ถ์ํ ์์ค: SQL ์ค์ฌ ๊ฐ๋ฐ์ ์ง์ํ๋ฉด์๋ ๋ฐ๋ณต ์ฝ๋๋ฅผ ์ค์ฌ์ค.
3) Spring JPA (Hibernate)
- ORM ๊ธฐ๋ฐ: ๊ฐ์ฒด์ ํ ์ด๋ธ ๊ฐ ๋งคํ์ ์ง์ค. SQL ์์ฑ์ด ๋ํญ ์ค์ด๋ฆ.
- ์๋ ์ฟผ๋ฆฌ ์์ฑ: ๋ฉ์๋ ์ด๋ฆ์ ๊ธฐ๋ฐ์ผ๋ก ์๋์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑ(
findById
,findByName
๋ฑ). - ๋์ ์์ฐ์ฑ: ํ๋ก์ ํธ๊ฐ ์ปค์ง์๋ก ์ ์ง๋ณด์, ํ์ฅ์ฑ์ด ํ์.
ํญ๋ชฉ | JDBC | Spring JDBC | Spring JPA (Hibernate) |
---|---|---|---|
์ถ์ํ ์์ค | ๋ฎ์ | ์ค๊ฐ | ๋์ |
์ฝ๋ ๊ฐ๊ฒฐ์ฑ | ๋ฎ์ | ๋์ | ๋งค์ฐ ๋์ |
์์ธ ์ฒ๋ฆฌ | ์ง์ ์ฒ๋ฆฌ | Spring ์์ธ ๋ณํ ์ง์ | Spring ์์ธ ๋ณํ + ORM ์ง์ |
์ฟผ๋ฆฌ ์์ฑ | ์ง์ SQL ์์ฑ | ์ง์ SQL ์์ฑ | ๋ฉ์๋ ๊ธฐ๋ฐ ์๋ ์์ฑ + JPQL |
์ ์ฐ์ฑ | ๋งค์ฐ ๋์ | ๋์ | ์ค๊ฐ (ORM ๊ท์น์ ๋ฐ๋ฆ) |
ํ์ต ๊ณก์ | ๋ฎ์ | ๋ฎ์ | ์ค๊ฐ~๋์ |
์ ์ง๋ณด์์ฑ | ๋ฎ์ | ์ค๊ฐ~๋์ | ๋์ |
๊ฒฐ๋ก ๐ฏ
ํ๋ก์ ํธ์ ๊ท๋ชจ๋ ์๊ตฌ์ฌํญ์ ๋ฐ๋ผ JDBC, Spring JDBC, Spring JPA๋ฅผ ์ ์ ํ ์ ํํด์ผ ํ๋ค.
- ๋จ์ํ ์ฟผ๋ฆฌ๋ ์ง์ ์ ์ด๊ฐ ํ์ํ ๊ฒฝ์ฐ: JDBC ๋๋ Spring JDBC๊ฐ ๋ ์ ํฉํ๋ค.
- ๋๊ท๋ชจ ์ํฐํ๋ผ์ด์ฆ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ ๊ฐ์ฒด ์งํฅ์ ๊ฐ๋ฐ์ ์ ํธํ๋ ๊ฒฝ์ฐ: Spring JPA(Hibernate)๋ฅผ ์ฌ์ฉํ๋ ํธ์ด ์์ฐ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ ์ธก๋ฉด์์ ์ ๋ฆฌํ๋ค.
๊ฐ๊ฐ์ ์ฅ๋จ์ ์ ์ ์ดํดํ๊ณ , ์ํฉ์ ๋ง์ถฐ ์ ์ ํ ํ์ฉํ๋ ๊ฒ์ด ์ค์ํ๋ค.