Spring ์ ๋ฌธ / 6. DB ์ ๊ทผ ๊ธฐ์
by rlaehddnd04221. H2 DB ์ค์น
H2 DB๋ ๊ฐ๋ฐ์ด๋ ํ ์คํธ ์ฉ๋๋ก ๊ฐ๋ณ๊ณ ํธ๋ฆฌํ DB, ์น ํ๋ฉด์ ์ ๊ณต
ํ ์ด๋ธ ์์ฑ
drop table if exists member CASCADE;
create table member
(
id bigint generated by default as identity,
name varchar(255),
primary key (id)
);
2. ์์ JDBC
ํ๊ฒฝ์ค์
build.gradle ํ์ผ์ jdbc, h2 ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๊ฐ
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
์คํ๋ง ๋ถํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์ค์ ์ถ๊ฐ
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
Jdbc ๋ฆฌํฌ์งํ ๋ฆฌ ๊ตฌํ
package kdo6301.spring0.repository;
import kdo6301.spring0.domain.Member;
import kdo6301.spring0.repository.MemberRepository;
import org.springframework.jdbc.datasource.DataSourceUtils;
import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class JdbcMemberRepository implements MemberRepository {
private final DataSource dataSource;
public JdbcMemberRepository(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Member save(Member member) {
String sql = "insert into member(name) values(?)";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection();
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);
}
}
@Override
public Optional<Member> findById(Long id) {
String sql = "select * from member where id = ?";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setLong(1, id);
rs = pstmt.executeQuery();
if(rs.next()) {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return Optional.of(member);
} else {
return Optional.empty();
}
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs);
} }
@Override
public List<Member> findAll() {
String sql = "select * from member";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
List<Member> members = new ArrayList<>();
while(rs.next()) {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
members.add(member);
}
return members;
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs);
}
}
@Override
public Optional<Member> findByName(String name) {
String sql = "select * from member where name = ?";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
rs = pstmt.executeQuery();
if(rs.next()) {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return Optional.of(member);
}
return Optional.empty();
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs);
}
}
private Connection getConnection() {
return DataSourceUtils.getConnection(dataSource);
}
private void close(Connection conn, PreparedStatement pstmt, ResultSet rs)
{
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
} try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
close(conn);
}
} catch (SQLException e) {
e.printStackTrace();
} }
private void close(Connection conn) throws SQLException {
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
- DataSource๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค๋ฅ์ ์ ํ๋ํ ๋ ์ฌ์ฉํ๋ ๊ฐ์ฒด.
- SpringBoot๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค๋ฅ์ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก DataSource๋ฅผ ์์ฑํ๊ณ ์คํ๋ง ๋น์ผ๋ก ๋ง๋ค์ด๋๋ค. ๊ทธ๋์ DI๋ฅผ ๋ฐ์ ์ ์๋ค.
-
๊ฐ๋ฐฉ-ํ์ ์์น(OCP, Open-Closed Principle) ํ์ฅ์๋ ์ด๋ ค์๊ณ , ์์ , ๋ณ๊ฒฝ์๋ ๋ซํ์๋ค.
์คํ๋ง์ DI (Dependencies Injection)์ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด ์ฝ๋๋ฅผ ์ ํ ์๋์ง ์๊ณ , ์ค์ ๋ง์ผ๋ก ๊ตฌํ ํด๋์ค๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค.
ํ์์ ๋ฑ๋กํ๊ณ DB์ ๊ฒฐ๊ณผ๊ฐ ์ ์ ๋ ฅ๋๋์ง ํ์ธํด๋ณด๋ฉด ๋ฐ์ดํฐ๋ฅผ DB์ ์ ์ฅํ๋ฏ๋ก ์คํ๋ง ์๋ฒ๋ฅผ ๋ค์ ์คํํด๋ ๋ฐ์ดํฐ๊ฐ ์์ ํ๊ฒ ์ ์ฅ๋๋ค.
๊ทธ ์ธ์ ์ฝ๋๊ฐ ๋๋ฌด ์ฅํฉํ๊ณ ์ฌ๋ํ ๋ฐฉ์์ด๋ผ ์ฝ๋์ ๋ํ ์ค๋ช ์๋ต. ์ด๋ ๊ฒ ์งฐ๋ค ์ฐธ๊ณ ๋ง ํ๊ณ ๋์ด๊ฐ
3. ์คํ๋ง ํตํฉ ํ ์คํธ
package kdo6301.spring0.service;
import kdo6301.spring0.domain.Member;
import kdo6301.spring0.repository.MemberRepository;
import kdo6301.spring0.repository.MemoryMemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
class MemberServiceIntegrationTest {
@Autowired MemberService memberService;
@Autowired MemberRepository memberRepository;
@Test
void join()
{
//given
Member member = new Member();
member.setName("Kim");
//when
Long saveId = memberService.join(member);
//then
Member One = memberService.findOne(saveId).get();
Assertions.assertThat(member.getName()).isEqualTo(One.getName());
}
@Test
void ์ค๋ณตํ์์์ธ()
{
// given
Member mem1 = new Member();
mem1.setName("Spring1");
Member mem2 = new Member();
mem2.setName("Spring1");
// when
memberService.join(mem1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(mem2));
Assertions.assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์ฌํ๋ ํ์์
๋๋ค.");
// try
// {
// memberService.join(mem2);
// fail();
// }catch(IllegalStateException e){
// Assertions.assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์ฌํ๋ ํ์์
๋๋ค.");
// }
// then
}
}
์์ MemoryMemberRepository๋ฅผ ์ฌ์ฉํ ๋์๋, @BeforeEach๋ @AfterEach๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ ์ผ์ด์ค๋ฅผ ๋๋ฆด ๋ ๋ง๋ค ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ์ด๊ธฐํ ํด์ฃผ์ด ๊ฐ ํ ์คํธ๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ์คํํ์๋ค.
+ ์ฐ๋ฆฌ๋ JDBC DB๋ฅผ ์ด์ฉํ์ฌ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ผ๋ฏ๋ก ๊ธฐ์กด์ ์๋ MemoryMemberRepository๊ฐ ์๋ MemberRepository๋ก ๋ณ๊ฒฝํ์๋ค.
@Transactional ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ฉด ํ ์คํธ ์งํ ์ ์ ํธ๋์ญ์ ์ ์์ํ๊ณ , ํ ์คํธ ์๋ฃ ํ์๋ ํญ์ ๋กค๋ฐฑ์ ์งํํ๋ค.
์ด๋ ๊ฒ ํ๋ฉด DB์ ๋ฐ์ดํฐ๊ฐ ๋จ์ง ์์ ๋ค์ ํ ์คํธ์ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
@SpringBootTest๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ฒด Bean์ ๋ชจ๋ ๊ฐ์ ธ์ค๊ณ , ํ ์คํธ๋ฅผ ํจ๊ป ์งํํ๋ค. ์ฝ๊ฒ ๋งํด ์คํ๋ง ์ปจํ ์ด๋์ ํ ์คํธ๋ฅผ ํจ๊ป ์คํํ๋ค.
4. ์คํ๋ง JdbcTemplate
์์ Jdbc์ ๋์ผํ ํ๊ฒฝ์ค์ ์ ํ๋ฉด ๋๋ค.
์คํ๋ง JdbcTemplate๊ณผ MyBatis ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ JDBC API์์ ๋ณธ ๋ฐ๋ณต ์ฝ๋๋ฅผ ๋๋ถ๋ถ ์ ๊ฑฐํด์ค๋ค. ํ์ง๋ง SQL์ ์ง์ ์์ฑํด์ผ ํ๋ค.
์คํ๋ง JdbcTemplate ํ์ ๋ฆฌํฌ์งํ ๋ฆฌ
package kdo6301.spring0.repository;
import kdo6301.spring0.domain.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class JdbcTemplateMemberRepository implements MemberRepository{
private final JdbcTemplate jdbcTemplate;
// ์์ฑ์๊ฐ ํ๋์ผ ๋ ์๋ต ๊ฐ๋ฅ @Autowired
public JdbcTemplateMemberRepository(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public Member save(Member member) {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("member").usingGeneratedKeyColumns("id");
Map<String, Object> parameters = new HashMap<>();
parameters.put("name", member.getName());
Number key = jdbcInsert.executeAndReturnKey(new
MapSqlParameterSource(parameters));
member.setId(key.longValue());
return member;
}
@Override
public Optional<Member> findById(Long id) {
List<Member> result = jdbcTemplate.query("select * from member where id = ?", memberRowMapper(),id);
return result.stream().findAny();
}
@Override
public Optional<Member> findByName(String name) {
List<Member> result = jdbcTemplate.query("select * from member where name = ?", memberRowMapper(), name);
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
return jdbcTemplate.query("select * from member", memberRowMapper());
}
private RowMapper<Member> memberRowMapper()
{
return (rs, rowNum) -> {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return member;
};
}
}
0. memberRowMapper
- RowMapper๋ฅผ ์ฌ์ฉํ๋ฉด ์ํ๋ ํํ์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ ์ ์๋ค.
return (rs, rowNum) -> {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return member;
};
member๋ฅผ ์์ฑํ๊ณ resultset rs๋ก๋ถํฐ ์์ด๋์ ์ด๋ฆ์ ๋ฐ์์ member๊ฐ์ฒด์ ์ ์ฅํ๋ค.
1. findByID , name, All
query์ ๋ํ ๊ฒฐ๊ด๊ฐ์ memberRowMapper()์ ๋งคํํ์ฌ ๋ฆฌ์คํธ ํํ๋ก ๋ฆฌํด
JdbcTemplate์ ์ฌ์ฉํ๋๋ก ์คํ๋ง ์ค์ ๋ณ๊ฒฝ
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
return new JdbcMemberRepository(dataSource);
return new JdbcTemplateMemberRepository(dataSource);
}
5. JPA
- JPA๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด์ ๋ฐ๋ณต์ฝ๋๋ ๋ฌผ๋ก ์ด๊ณ , ๊ธฐ๋ณธ์ ์ธ SQL๋ JPA๊ฐ ์ง์ ๋ง๋ค์ด์ ์คํํด์ค๋ค.
- JPA๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ฐ ์์ฐ์ฑ์ ํฌ๊ฒ ๋์ผ ์ ์์
- JPA๋ฅผ ์ฌ์ฉํ๋ฉด, SQL๊ณผ ๋ฐ์ดํฐ ์ค์ฌ์ ์ค๊ณ์์ ๊ฐ์ฒด ์ค์ฌ์ ์ค๊ณ๋ก ํจ๋ฌ๋ค์์ ์ ํ์ ํ ์ ์๋ค.
JPA ์ํฐํฐ ๋งคํ
package kdo6301.spring0.domain;
import jdk.jfr.Name;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
JPA ํ์ ๋ฆฌํฌ์งํ ๋ฆฌ
package kdo6301.spring0.repository;
import kdo6301.spring0.domain.Member;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
public class JpaMemberRepository implements MemberRepository{
private final EntityManager em;
public JpaMemberRepository(EntityManager em) {
this.em = em;
}
@Override
public Member save(Member member) {
em.persist(member);
return member;
}
@Override
public Optional<Member> findById(Long id) {
Member member = em.find(Member.class, id);
return Optional.ofNullable(member);
}
@Override
public Optional<Member> findByName(String name) {
List<Member> result = em.createQuery("select m from Member as m where m.name = :name",Member.class)
.setParameter("name",name)
.getResultList();
return result.stream().findAny();
}
@Override
public List<Member> findAll() {
return em.createQuery("select m from Member as m",Member.class).getResultList();
}
}
JPA๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ฐ์ฝ๋๋ค์ด ํ์ฐํ๊ฒ ์ค์ด๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์๋น์ค ๊ณ์ธต์ ํธ๋์ญ์ ์ถ๊ฐ
import org.springframework.transaction.annotation.Transactional
@Transactional
public class MemberService {}
์คํ๋ง์ ํด๋น ํด๋์ค์ ๋ฉ์๋๋ฅผ ์คํํ ๋ ํธ๋์ญ์ ์ ์์ํ๊ณ ๋ฉ์๋๊ฐ ์ข ๋ฃ๋๋ฉด ํธ๋์ญ์ ์ ์ปค๋ฐํ๋ค.
JPA๋ฅผ ํตํ ๋ชจ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ํธ๋์ญ์ ์์์ ์คํํด์ผ ํ๋ค.
๋น ๊ณ์ธต ๋ณ๊ฒฝ
@Bean
public MemberRepository memberRepository() {
// return new MemoryMemberRepository();
// return new JdbcMemberRepository(dataSource);
// return new JdbcTemplateMemberRepository(dataSource);
return new JpaMemberRepository(em);
}
6. ์คํ๋ง ๋ฐ์ดํฐ JPA
์คํ๋ง ๋ถํธ์ JPA๋ง ์ฌ์ฉํด๋ ๊ฐ๋ฐ์์ฐ์ฑ์ด ๋ง์ด ์ฆ๊ฐํ์ง๋ง, ์ฌ๊ธฐ์ ๋๋ถ์ด ์คํ๋ง ๋ฐ์ดํฐ JPA๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด์ ํ๊ณ๋ฅผ ๋์ด ์ธํฐํ์ด์ค ๋ง์ผ๋ก ๊ฐ๋ฐ์ ์๋ฃํ ์ ์๋ค.
์คํ๋ง ๋ฐ์ดํฐ JPA๋ JPA๋ฅผ ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ๋๋ก ๋์์ฃผ๋ ๊ธฐ์ ๋ก JPA๋ฅผ ๋จผ์ ๋ฐฐ์ดํ์ ์คํ๋ง ๋ฐ์ดํฐ JPA๋ฅผ ํ์ตํ๋ ๊ฒ์ด ์ข๋ค.
์คํ๋ง ๋ฐ์ดํฐ JPA ํ์ ๋ฆฌํฌ์งํ ๋ฆฌ
package kdo6301.spring0.repository;
import kdo6301.spring0.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository{
// JPQL - select m from Member as m where m.name = ?
@Override
Optional<Member> findByName(String name);
}
๋ฌธ๋ฒ / interface๋ extends๋ฅผ ํตํด ๋ค์ค ์์์ด ๊ฐ๋ฅํ๋ค.
JpaRepository์๋ findAll(), saveAll() ๋ฑ๊ณผ ๊ฐ์ ๋ฉ์๋๋ค์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๊ตฌํ๋์ด ์๋๋ฐ ์ด ๊ธฐ๋ณธ ๋ฉ์๋์ธ์ findByName, findById ๊ฐ์ ๋ฉ์๋๋ค์ ๋ฉ์๋ ์ด๋ฆ์ ํตํด JPA๊ฐ JPQL๋ฌธ์ ์์ฑํ์ฌ ์๋์ ์ผ๋ก ๊ธฐ๋ฅ์ ๊ตฌํํ์ฌ ์ ๊ณตํด์ค๋ค !
- ์คํ๋ง ๋ฐ์ดํฐ JPA ์ ๊ณต ๊ธฐ๋ฅ
- JpaRepository์๋ findByName() , findByEmail() ์ฒ๋ผ ๋ฉ์๋ ์ด๋ฆ์ ํตํ ์กฐํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
- ํ์ด์ง ๊ธฐ๋ฅ ์ ๊ณต
- ์ธํฐํ์ด์ค๋ฅผ ํตํ ๊ธฐ๋ณธ์ ์ธ CRUD
โ๏ธ์ฐธ๊ณ
์ค๋ฌด์์๋ JPA์ ์คํ๋ง ๋ฐ์ดํฐ JPA๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ๊ณ , ๋ณต์กํ ๋์ ์ฟผ๋ฆฌ๋ Querydsl์ด๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. Querydsl์ ์ฌ์ฉํ๋ฉด ์ฟผ๋ฆฌ๋ ์๋ฐ ์ฝ๋๋ก ์์ ํ๊ฒ ์์ฑํ ์ ์๊ณ , ๋์ ์ฟผ๋ฆฌ๋ ํธ๋ฆฌํ๊ฒ ์์ฑํ ์ ์๋ค.
์ด ์กฐํฉ์ผ๋ก ํด๊ฒฐํ๊ธฐ ์ด๋ ค์ด ์ฟผ๋ฆฌ๋ JPA๊ฐ ์ ๊ณตํ๋ ๋ค์ดํฐ๋ธ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, ์์ ํ์ตํ ์คํ๋ง JdbcTemplate๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
์คํ๋ง ๋น์ ๋ฑ๋ก
package kdo6301.spring0;
import kdo6301.spring0.repository.*;
import kdo6301.spring0.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
@Autowired
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService()
{
return new MemberService(memberRepository);
}
// @Bean
// public MemberRepository memberRepository()
// {
//// return new JdbcMemberRepository(dataSource);
//// return new JdbcTemplateMemberRepository(dataSource);
//// return new JpaMemberRepository(em);
//
// }
}
์คํ๋ง ๋ฐ์ดํฐ JPA๊ฐ SpringDataJpaMemberRepository๋ฅผ ์คํ๋ง ๋น์ผ๋ก ์๋ ๋ฑ๋กํด์ค๋ค.
<์ ๋ฆฌ>
> H2๋ฅผ ์ค์นํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ค์นํ์ฌ ์์ํ jdbc ๊ธฐ์ ๋ก ์ฌ์ฉํด ๋ดค๋๋ ๋ฉ์๋ ํ๋ํ๋ ๊ตฌํ ํํธ๊ฐ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๊ณ ์ฝ๋๊ฐ ์ฅํฉํจ.
> ํตํฉํ ์คํธ๋ฅผ ๋ง๋ค์ด๋ณด์์
> Jdbctemplate ๋ฅผ ์ฌ์ฉํด๋ดค์ง๋ง sql ์ง์ ์์ฑํด์ผ ํ๋ค๋ ๋จ์ ์ด ์์์
> jpa๋ ๊ธฐ๋ณธ์ ์ธ crud(create, read, update, delete) ํ๋๋ฐ ์ฟผ๋ฆฌ ์์ฑํ ํ์ ์์์
> ์คํ๋ง ๋ฐ์ดํฐ jpa๋ฅผ ์ฌ์ฉํด๋ณด๋ ์์ ๊ตฌํ ํด๋์ค๋ฅผ ์์ฑํ ํ์๊ฐ ์์ด ์ธํฐํ์ด์ค๋ง์ผ๋ก ๊ฐ๋ฐ์ ํ ์ ์์์
<์ฐธ๊ณ ์๋ฃ>
'๐ Backend' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] OOP 5๊ฐ์ง ์ค๊ณ์์น (2) | 2023.01.23 |
---|---|
Spring ์ ๋ฌธ / 7. AOP (0) | 2023.01.19 |
Spring ์ ๋ฌธ / 5. ํ์ ๊ด๋ฆฌ ์์ - ์น MVC ๊ฐ๋ฐ (1) | 2023.01.17 |
Spring ์ ๋ฌธ / 4. ์คํ๋ง ๋น๊ณผ ์์กด๊ด๊ณ (0) | 2023.01.17 |
Spring ์ ๋ฌธ / 3. ํ์ ๊ด๋ฆฌ ์์ - ๋ฐฑ์๋ ๊ฐ๋ฐ (0) | 2023.01.16 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
Study Repository
rlaehddnd0422