์ฐํ ์ฝ ๋ ๋ฒจ2 ๋ฏธ์ ์ ์งํํ๋ฉด์ Dao์ Repository์ ์ฐจ์ด์ ๋ํด์ ๋ง์ ์ด์ผ๊ธฐ๊ฐ ์ค๊ณ ๊ฐ๋ ๊ฒ์ ๋๊ผ๋ค.
ํ์ง๋ง ์์ง Dao๋ง์ผ๋ก๋ ์ถฉ๋ถํ๊ธฐ ๋๋ฌธ์ Repository์ ๋ํด์ ๊น๊ฒ ์๊ฐํด๋ณด์ง ์์๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ฒ ์งํ์ฒ ๋ฏธ์ ์์ ์๊ตฌ์ฌํญ์ด ๋ณต์กํด์ง๋ฉด์ ์ฌ๋ฌ Dao๋ค์ด ์๊ฒผ๊ณ , Repository๋ฅผ ์จ์ผ ํ๋ ์ํฉ์ด ์๋ค.
ํ์ด๊ฐ ์ ์ํด์ ์ฌ์ฉํ๊ธด ํ์ง๋ง, Repository์ ํ์์ฑ์ ์กฐ๊ธ ๋๋ ๊ฒ ๊ฐ์๋ค.
๊ทธ๋์ Dao์ Repository์ ๋ํด์ ์ ๋๋ก ์์๋ณด๊ธฐ๋ก ํ๋ค!
DAO๋?
Data Access Object์ ์ฝ์๋ก, ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฐ์ฒด์ด๋ค.
์น ์ ํ๋ฆฌ์ผ์ด์ ์ํคํ ์ฒ์ Application ๊ณ์ธต์์ ๋ฐ๋ก ๋ฐ์ดํฐ์ ์ ๊ทผ์ ํ๋ ๊ฒ์ด ์๋๋ผ, Dao(Persistence ๊ณ์ธต)๋ฅผ ๊ฑฐ์ณ์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ค.
์ฆ, ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ์ ์ฅํ๊ณ ์กฐํํ๋์ง, ๋ฌด์จ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋์ง๋ฅผ Application ๊ณ์ธต์ ๋ชจ๋ฅธ๋ค.
์๋์ ๊ฐ์ด Product๋ผ๋ ํ ์ด๋ธ์ ๋ํ ์ ๊ทผ์ Dao๋ฅผ ํตํด์ ํ๋ค.
public class ProductDao {
private final RowMapper<Product> productRowMapper = // ์๋ต..
private final JdbcTemplate jdbcTemplate;
public ProductDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public int save(Product product) {
String sqlForSave = "INSERT INTO Product (name, price, image_url) VALUES (?, ?, ?)";
// ์๋ต
return keyHolder.getKey().intValue();
}
public void deleteById(int id) {
String sqlForDeleteById = "DELETE FROM Product WHERE id = ?";
jdbcTemplate.update(sqlForDeleteById, id);
}
public void updateById(int id, Product product) {
String sqlForUpdateById = "UPDATE Product SET name = ?, price = ?, image_url = ? WHERE id = ?";
jdbcTemplate.update(sqlForUpdateById, product.getName(), product.getPrice(), product.getImageUrl(), id);
}
public List<Product> selectAll() {
String sqlForSelectAll = "SELECT * FROM Product";
return jdbcTemplate.query(sqlForSelectAll, productRowMapper);
}
}
์ด์ ๊น์ง๋ ์๊ตฌ์ฌํญ์ด ๊ฐ๋จํด์ Application(Service) ๊ณ์ธต์ด ํ๋์ Dao๋ง์ ์์กดํ๋๋ก ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
@Service
public class ProductService {
private final ProductDao productDao;
public ProductService(ProductDao productDao) {
this.productDao = productDao;
}
public int add(ProductAddRequestDto productAddRequestDto) {
Product product = productAddRequestDto.toEntity();
return productDao.save(product);
}
// ๋ฑ๋ฑ..
}
ํ๋์ Dao์ ์ ๊ทผ๋ง์ผ๋ก๋ ์์ ํ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ฐ๋ฐ ์งํ์ฒ ๋ฏธ์ ์ ์๊ตฌ์ฌํญ์ด ๋ณต์กํ์ฌ, Line์ด๋ผ๋ ๊ฐ์ฒด๋ฅผ ์กฐํํ๊ธฐ ์ํด์๋ Section๊ณผ Station์ ์ ๋ณด๋ ํ์ํ๋ค.
๊ทธ๋ฌ๋ค ๋ณด๋ ์๋น์ค์์ ์ฌ๋ฌ Dao๋ฅผ ์์กดํ๊ฒ ๋์๊ณ , ์กฐํํ ๊ฐ์ฒด๋ค์ ์กฐํฉํด์ Line์ ๋ง๋ค์ด์ผ ํ๋ค.
๊ทธ๋์ Repository ๊ฐ๋ ์ ๋์ ํ๋ค.
Repository๋?
Eric Evans์ DDD์์ ๋์จ ๊ฐ๋ ์ผ๋ก, "Repository๋ ์ ์ฅ, ๊ฒ์, ์กฐํ ๋ฑ์ ๋์์ ์บก์ํํ๋ ๋ฉ์ปค๋์ฆ์ผ๋ก, ๊ฐ์ฒด ์ปฌ๋ ์ ์ ์ถ์ํ"๋ผ๊ณ ํ๋ค.
๊ทธ๋ฆฌ๊ณ Patterns of Enterprise Application Architecture์์๋ "๋๋ฉ์ธ ๊ฐ์ฒด์ ์ก์ธ์ค ํ๊ธฐ ์ํ ์ปฌ๋ ์ ๊ณผ ์ ์ฌํ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ์ ๋ฐ์ดํฐ ๋งคํ ๋ ์ด์ด ์ฌ์ด๋ฅผ ์ค์ฌํ๋ค."๋ผ๊ณ ์ค๋ช ํ๋ค.
์ ๋ฆฌํ๋ฉด
- ๊ฐ์ฒด์ ์ปฌ๋ ์ ์ ์ถ์ํ
- ๋๋ฉ์ธ ๊ฐ์ฒด์ ๋ ๊ฐ๊น์ด ์์ ์์ค ๊ฐ๋
- ๋๋ฉ์ธ๊ณผ ๋ฐ์ดํฐ ์ก์ธ์ค ๊ณ์ธต ์ฌ์ด์ ์กด์ฌ
๋ผ๊ณ ํ ์ ์๋ค.
๋ง๋ก๋ง ๋ค์ด์๋ ์ดํดํ๊ธฐ ์ด๋ ต๋ค. ๊ฐ์ฒด์ ์ปฌ๋ ์ ์ ์ถ์ํ๊ฐ ๋ญ์ง? ๋ฐ๋ก ๋ค์ ์ฝ๋๋ฅผ ํ์ธํด ๋ณด์.
@Repository
public class LineRepository {
private final LineDao lineDao;
private final SectionDao sectionDao;
private final StationDao stationDao;
public LineRepository(LineDao lineDao, SectionDao sectionDao, StationDao stationDao) {
this.lineDao = lineDao;
this.sectionDao = sectionDao;
this.stationDao = stationDao;
}
public Line findById(final Long id) {
LineEntity lineEntity = lineDao.findById(id);
List<SectionEntity> sectionEntities = sectionDao.findByLineId(lineEntity.getId());
List<StationEntity> stationEntities = stationDao.findByLineId(lineEntity.getId());
return toLine(lineEntity, sectionEntities, stationEntities);
}
}
Line ๊ฐ์ฒด๋ Section(์ญ๊ณผ ์ญ ์ฌ์ด์ ๊ตฌ๊ฐ)๊ณผ Station์ ์ ๋ณด๋ก ์ด๋ฃจ์ด์ง ๊ฐ์ฒด์ด๋ค.
๊ทธ๋์ Line์ ์กฐํํ๊ธฐ ์ํด์ LineDao, SectionDao, StationDao๊ฐ ๋ชจ๋ ํ์ํ๋ค.
์ด๋ฐ ๊ฒฝ์ฐ LineService์์๋ Line์ ์กฐํํ๋ ๊ฒ ๋ชฉ์ ์ด์ง, Line์ ์ด๋ป๊ฒ ์กฐํํ๋์ง๋ ๊ด์ฌ์ด ์๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋์ง ์กฐ์ฐจ๋ ์ ํ์๊ฐ ์๋ค. ๊ทธ๋ฅ LineRepository์๊ฒ "Line์ ์ฐพ์์ค"๋ผ๊ณ ์์ฒญ์ ํ๊ณ , Line์ ๋ฐ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
๊ทธ๋ผ LineRepository ๋ด๋ถ์์๋ ํ์ํ ์ฌ๋ฌ Dao๋ค์ ์ฌ์ฉํด์ ์กฐ๋ฆฝํ Line์ ๋ฐํ์ ํ๋ค.
๋ง์ฝ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฐ์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐ๋ InMemoryLineDao๋ผ๋ Dao๋ฅผ ์ด๋ค๊ณ ํด๋ Application ๊ณ์ธต์ LineRepository ๋ด๋ถ ๊ตฌํ๊ณผ๋ ์๊ด์์ด ๋๊ฐ์ด ๋์ํ๋ค.
์ด์ ๋ ๊ฐ์ฒด์ ์ปฌ๋ ์ ์ด๋ผ๋ ๋ง์ด ์ดํด๊ฐ ๋๋ค.
LineRepository๋ Line์ ์กฐํํ๊ณ ์ ์ฅํ๋ ๋ฑ์ ๋์์ ํ๋ Line์ ์ปฌ๋ ์ ์ด๋ผ๊ณ ๋ณผ ์ ์๋ค.
์ด๋ ๊ฒ Application๊ณ์ธต๊ณผ Persistence ๊ณ์ธต ์ฌ์ด์ Repository๋ฅผ ๋ ์ผ๋ก์จ ๊ด์ฌ์ฌ๋ฅผ ํ ๋ฒ ๋ ๋ถ๋ฆฌํ ์ ์๋ค.
์์ง ๊ฒฝํ์ด ๋ถ์กฑํด์ ์์ ์ค๋ช ์ด ์กฐ๊ธ์ ๋ถ์คํ ์ ์๋ค. ์กฐ๊ธ ๋ ๋ง์ ๊ฒฝํ์ ํด๋ด์ผ ํ ๊ฒ ๊ฐ๋ค.
๊ฒฐ๋ก ์ Repository๋ฅผ ์ฌ์ฉํด๋ณด์๋๋ ์ฝ๋๋ ๊น๋ํด์ง๊ณ ๊ฐ ๋ ์ด์ด์ ์ฑ ์์ ์กฐ๊ธ ๋ ํ์คํ๊ฒ ๋ถ๋ฆฌํ ์ ์์๋ค. ๐
์ฐธ๊ณ ์๋ฃ
https://www.baeldung.com/java-dao-vs-repository
'Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring Boot] Graceful shutdown์ผ๋ก ์์ ํ๊ฒ ์ข ๋ฃํ๊ธฐ (0) | 2024.08.30 |
---|---|
[JPA] ์ฐ๊ด๊ด๊ณ ๋งคํ ์ ๋ฆฌ (0) | 2023.07.13 |
[Spring] Interceptor๋ ์ด๋ป๊ฒ ๋์ํ ๊น? - DispatcherServlet ๋ด๋ถ ์ฝ๋ ์ดํด๋ณด๊ธฐ (0) | 2023.05.08 |
Mockito.mock(), @Mock๊ณผ @MockBean์ ์ฐจ์ด์ (1) | 2023.04.23 |
์ฐํ ์ฝ ๋ ๋ฒจ2 ๋ฏธ์ ์ ์งํํ๋ฉด์ Dao์ Repository์ ์ฐจ์ด์ ๋ํด์ ๋ง์ ์ด์ผ๊ธฐ๊ฐ ์ค๊ณ ๊ฐ๋ ๊ฒ์ ๋๊ผ๋ค.
ํ์ง๋ง ์์ง Dao๋ง์ผ๋ก๋ ์ถฉ๋ถํ๊ธฐ ๋๋ฌธ์ Repository์ ๋ํด์ ๊น๊ฒ ์๊ฐํด๋ณด์ง ์์๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ฒ ์งํ์ฒ ๋ฏธ์ ์์ ์๊ตฌ์ฌํญ์ด ๋ณต์กํด์ง๋ฉด์ ์ฌ๋ฌ Dao๋ค์ด ์๊ฒผ๊ณ , Repository๋ฅผ ์จ์ผ ํ๋ ์ํฉ์ด ์๋ค.
ํ์ด๊ฐ ์ ์ํด์ ์ฌ์ฉํ๊ธด ํ์ง๋ง, Repository์ ํ์์ฑ์ ์กฐ๊ธ ๋๋ ๊ฒ ๊ฐ์๋ค.
๊ทธ๋์ Dao์ Repository์ ๋ํด์ ์ ๋๋ก ์์๋ณด๊ธฐ๋ก ํ๋ค!
DAO๋?
Data Access Object์ ์ฝ์๋ก, ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฐ์ฒด์ด๋ค.
์น ์ ํ๋ฆฌ์ผ์ด์ ์ํคํ ์ฒ์ Application ๊ณ์ธต์์ ๋ฐ๋ก ๋ฐ์ดํฐ์ ์ ๊ทผ์ ํ๋ ๊ฒ์ด ์๋๋ผ, Dao(Persistence ๊ณ์ธต)๋ฅผ ๊ฑฐ์ณ์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ค.
์ฆ, ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ์ ์ฅํ๊ณ ์กฐํํ๋์ง, ๋ฌด์จ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋์ง๋ฅผ Application ๊ณ์ธต์ ๋ชจ๋ฅธ๋ค.
์๋์ ๊ฐ์ด Product๋ผ๋ ํ ์ด๋ธ์ ๋ํ ์ ๊ทผ์ Dao๋ฅผ ํตํด์ ํ๋ค.
public class ProductDao {
private final RowMapper<Product> productRowMapper = // ์๋ต..
private final JdbcTemplate jdbcTemplate;
public ProductDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public int save(Product product) {
String sqlForSave = "INSERT INTO Product (name, price, image_url) VALUES (?, ?, ?)";
// ์๋ต
return keyHolder.getKey().intValue();
}
public void deleteById(int id) {
String sqlForDeleteById = "DELETE FROM Product WHERE id = ?";
jdbcTemplate.update(sqlForDeleteById, id);
}
public void updateById(int id, Product product) {
String sqlForUpdateById = "UPDATE Product SET name = ?, price = ?, image_url = ? WHERE id = ?";
jdbcTemplate.update(sqlForUpdateById, product.getName(), product.getPrice(), product.getImageUrl(), id);
}
public List<Product> selectAll() {
String sqlForSelectAll = "SELECT * FROM Product";
return jdbcTemplate.query(sqlForSelectAll, productRowMapper);
}
}
์ด์ ๊น์ง๋ ์๊ตฌ์ฌํญ์ด ๊ฐ๋จํด์ Application(Service) ๊ณ์ธต์ด ํ๋์ Dao๋ง์ ์์กดํ๋๋ก ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
@Service
public class ProductService {
private final ProductDao productDao;
public ProductService(ProductDao productDao) {
this.productDao = productDao;
}
public int add(ProductAddRequestDto productAddRequestDto) {
Product product = productAddRequestDto.toEntity();
return productDao.save(product);
}
// ๋ฑ๋ฑ..
}
ํ๋์ Dao์ ์ ๊ทผ๋ง์ผ๋ก๋ ์์ ํ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ฐ๋ฐ ์งํ์ฒ ๋ฏธ์ ์ ์๊ตฌ์ฌํญ์ด ๋ณต์กํ์ฌ, Line์ด๋ผ๋ ๊ฐ์ฒด๋ฅผ ์กฐํํ๊ธฐ ์ํด์๋ Section๊ณผ Station์ ์ ๋ณด๋ ํ์ํ๋ค.
๊ทธ๋ฌ๋ค ๋ณด๋ ์๋น์ค์์ ์ฌ๋ฌ Dao๋ฅผ ์์กดํ๊ฒ ๋์๊ณ , ์กฐํํ ๊ฐ์ฒด๋ค์ ์กฐํฉํด์ Line์ ๋ง๋ค์ด์ผ ํ๋ค.
๊ทธ๋์ Repository ๊ฐ๋ ์ ๋์ ํ๋ค.
Repository๋?
Eric Evans์ DDD์์ ๋์จ ๊ฐ๋ ์ผ๋ก, "Repository๋ ์ ์ฅ, ๊ฒ์, ์กฐํ ๋ฑ์ ๋์์ ์บก์ํํ๋ ๋ฉ์ปค๋์ฆ์ผ๋ก, ๊ฐ์ฒด ์ปฌ๋ ์ ์ ์ถ์ํ"๋ผ๊ณ ํ๋ค.
๊ทธ๋ฆฌ๊ณ Patterns of Enterprise Application Architecture์์๋ "๋๋ฉ์ธ ๊ฐ์ฒด์ ์ก์ธ์ค ํ๊ธฐ ์ํ ์ปฌ๋ ์ ๊ณผ ์ ์ฌํ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ์ ๋ฐ์ดํฐ ๋งคํ ๋ ์ด์ด ์ฌ์ด๋ฅผ ์ค์ฌํ๋ค."๋ผ๊ณ ์ค๋ช ํ๋ค.
์ ๋ฆฌํ๋ฉด
- ๊ฐ์ฒด์ ์ปฌ๋ ์ ์ ์ถ์ํ
- ๋๋ฉ์ธ ๊ฐ์ฒด์ ๋ ๊ฐ๊น์ด ์์ ์์ค ๊ฐ๋
- ๋๋ฉ์ธ๊ณผ ๋ฐ์ดํฐ ์ก์ธ์ค ๊ณ์ธต ์ฌ์ด์ ์กด์ฌ
๋ผ๊ณ ํ ์ ์๋ค.
๋ง๋ก๋ง ๋ค์ด์๋ ์ดํดํ๊ธฐ ์ด๋ ต๋ค. ๊ฐ์ฒด์ ์ปฌ๋ ์ ์ ์ถ์ํ๊ฐ ๋ญ์ง? ๋ฐ๋ก ๋ค์ ์ฝ๋๋ฅผ ํ์ธํด ๋ณด์.
@Repository
public class LineRepository {
private final LineDao lineDao;
private final SectionDao sectionDao;
private final StationDao stationDao;
public LineRepository(LineDao lineDao, SectionDao sectionDao, StationDao stationDao) {
this.lineDao = lineDao;
this.sectionDao = sectionDao;
this.stationDao = stationDao;
}
public Line findById(final Long id) {
LineEntity lineEntity = lineDao.findById(id);
List<SectionEntity> sectionEntities = sectionDao.findByLineId(lineEntity.getId());
List<StationEntity> stationEntities = stationDao.findByLineId(lineEntity.getId());
return toLine(lineEntity, sectionEntities, stationEntities);
}
}
Line ๊ฐ์ฒด๋ Section(์ญ๊ณผ ์ญ ์ฌ์ด์ ๊ตฌ๊ฐ)๊ณผ Station์ ์ ๋ณด๋ก ์ด๋ฃจ์ด์ง ๊ฐ์ฒด์ด๋ค.
๊ทธ๋์ Line์ ์กฐํํ๊ธฐ ์ํด์ LineDao, SectionDao, StationDao๊ฐ ๋ชจ๋ ํ์ํ๋ค.
์ด๋ฐ ๊ฒฝ์ฐ LineService์์๋ Line์ ์กฐํํ๋ ๊ฒ ๋ชฉ์ ์ด์ง, Line์ ์ด๋ป๊ฒ ์กฐํํ๋์ง๋ ๊ด์ฌ์ด ์๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋์ง ์กฐ์ฐจ๋ ์ ํ์๊ฐ ์๋ค. ๊ทธ๋ฅ LineRepository์๊ฒ "Line์ ์ฐพ์์ค"๋ผ๊ณ ์์ฒญ์ ํ๊ณ , Line์ ๋ฐ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
๊ทธ๋ผ LineRepository ๋ด๋ถ์์๋ ํ์ํ ์ฌ๋ฌ Dao๋ค์ ์ฌ์ฉํด์ ์กฐ๋ฆฝํ Line์ ๋ฐํ์ ํ๋ค.
๋ง์ฝ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฐ์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐ๋ InMemoryLineDao๋ผ๋ Dao๋ฅผ ์ด๋ค๊ณ ํด๋ Application ๊ณ์ธต์ LineRepository ๋ด๋ถ ๊ตฌํ๊ณผ๋ ์๊ด์์ด ๋๊ฐ์ด ๋์ํ๋ค.
์ด์ ๋ ๊ฐ์ฒด์ ์ปฌ๋ ์ ์ด๋ผ๋ ๋ง์ด ์ดํด๊ฐ ๋๋ค.
LineRepository๋ Line์ ์กฐํํ๊ณ ์ ์ฅํ๋ ๋ฑ์ ๋์์ ํ๋ Line์ ์ปฌ๋ ์ ์ด๋ผ๊ณ ๋ณผ ์ ์๋ค.
์ด๋ ๊ฒ Application๊ณ์ธต๊ณผ Persistence ๊ณ์ธต ์ฌ์ด์ Repository๋ฅผ ๋ ์ผ๋ก์จ ๊ด์ฌ์ฌ๋ฅผ ํ ๋ฒ ๋ ๋ถ๋ฆฌํ ์ ์๋ค.
์์ง ๊ฒฝํ์ด ๋ถ์กฑํด์ ์์ ์ค๋ช ์ด ์กฐ๊ธ์ ๋ถ์คํ ์ ์๋ค. ์กฐ๊ธ ๋ ๋ง์ ๊ฒฝํ์ ํด๋ด์ผ ํ ๊ฒ ๊ฐ๋ค.
๊ฒฐ๋ก ์ Repository๋ฅผ ์ฌ์ฉํด๋ณด์๋๋ ์ฝ๋๋ ๊น๋ํด์ง๊ณ ๊ฐ ๋ ์ด์ด์ ์ฑ ์์ ์กฐ๊ธ ๋ ํ์คํ๊ฒ ๋ถ๋ฆฌํ ์ ์์๋ค. ๐
์ฐธ๊ณ ์๋ฃ
https://www.baeldung.com/java-dao-vs-repository
'Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring Boot] Graceful shutdown์ผ๋ก ์์ ํ๊ฒ ์ข ๋ฃํ๊ธฐ (0) | 2024.08.30 |
---|---|
[JPA] ์ฐ๊ด๊ด๊ณ ๋งคํ ์ ๋ฆฌ (0) | 2023.07.13 |
[Spring] Interceptor๋ ์ด๋ป๊ฒ ๋์ํ ๊น? - DispatcherServlet ๋ด๋ถ ์ฝ๋ ์ดํด๋ณด๊ธฐ (0) | 2023.05.08 |
Mockito.mock(), @Mock๊ณผ @MockBean์ ์ฐจ์ด์ (1) | 2023.04.23 |