[스프링 입문] 스프링 예제 프로젝트 PetClinic 4
Portable Service Abstraction
Service Abstraction ?
스프링 PSA
-
예제(PetClinic)에서는 아래와 같이 Servlet을 형성하지 않는다.
// /owner/create public class OwnerCreateServlet extends HttpServlet { // GET @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } // POST @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
-
예제(PetClicin)에서는 아래와 같이 형성한다.
-
main\java\org\owner\OwnerController
@GetMapping("/owners/new") @LogExecutionTime public String initCreationForm(Map<String, Object> model) { Owner owner = new Owner(); model.put("owner", owner); return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } @PostMapping("/owners/new") @LogExecutionTime public String processCreationForm(@Valid Owner owner, BindingResult result) { if (result.hasErrors()) { return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; } else { this.owners.save(owner); return "redirect:/owners/" + owner.getId(); } }
@GetMapping
과@PostMapping
을 이용. -
@
을 사용했지만 그 아래 기반에는 서블릿 기반의 코드가 동작한다. (추상화 계층 사용)
-
-
PSA 사용 이유 : 참고 사이트
스프링 웹 M(odel) V(iew) C(ontroller)
-
@Controller
를 사용하면 요청을 맵핑(@RequestMapping
(@GetMapping
@PostMapping
등))private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm"; @GetMapping("/owners/new") //Controller @LogExecutionTime public String initCreationForm(Map<String, Object> model) { Owner owner = new Owner(); //Model model.put("owner", owner); return VIEWS_OWNER_CREATE_OR_UPDATE_FORM; //View }
/owners/new
와 같은 URL에 해당하는 요청이 들어왔을때, Method가 처리하도록 매핑(GetMapping)- MVC가 무엇에 해당하는지 꼭 확인하기.
-
P(ortable)이 붙은 이유 : 여러 기술을 다른 것으로 변화 가능하다.
-
Spring에서 제공하는 추상화 인터페이스 기능을 쓰지만 (아래)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
-
(위) 의존성을 추가하면 톰캣이 아닌 네티와 같은 서버에서도 Spring 기반의 프로그래밍이 구현된다.
-
결론 : Servlet/Reactive 를 선택할 수 있으며, 톰캣/네티/언더로우 등 서버 또한 바꿀 수 있다. !코드를 거의 변경하지 않고!
-
스프링 트랜잭션
-
트랜잭션 : 데이터의 하나의 작업 단위(처음부터 끝까지)
- 원자성(Atomicity) : 트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장
- 일관성(Consistency) : 트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지
- 고립성(Isolation) : 트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장
- 지속성(Durability) : 성공적으로 수행된 트랜잭션은 영원히 반영
-
아래의 코드를 보자. (Low Level의 트랙잭션 처리)
import java.math.BigDecimal; import java.sql.*; import java.time.LocalDateTime; public class TransactionExample { public static void main(String[] args) { try (Connection conn = DriverManager.getConnection( "jdbc:postgresql://127.0.0.1:5432/test", "postgres", "password"); Statement statement = conn.createStatement(); PreparedStatement psInsert = conn.prepareStatement(SQL_INSERT); PreparedStatement psUpdate = conn.prepareStatement(SQL_UPDATE)) { statement.execute(SQL_TABLE_DROP); statement.execute(SQL_TABLE_CREATE); // start transaction block conn.setAutoCommit(false); // default true // Run list of insert commands psInsert.setString(1, "mkyong"); psInsert.setBigDecimal(2, new BigDecimal(10)); psInsert.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now())); psInsert.execute(); psInsert.setString(1, "kungfu"); psInsert.setBigDecimal(2, new BigDecimal(20)); psInsert.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now())); psInsert.execute(); // Run list of update commands // error, test roolback // org.postgresql.util.PSQLException: No value specified for parameter 1. psUpdate.setBigDecimal(2, new BigDecimal(999.99)); //psUpdate.setBigDecimal(1, new BigDecimal(999.99)); psUpdate.setString(2, "mkyong"); psUpdate.execute(); // end transaction block, commit changes conn.commit(); // good practice to set it back to default true conn.setAutoCommit(true); } catch (Exception e) { e.printStackTrace(); } } //... }
conn.setAutoCommit(false);
: sql이 여러번 날아가더라도 커밋을 하지 않는다.- ~~
conn.commit();
: ~~ 코드를 마치고 커밋.
-
스프링의
@Transactional
: Annotation이 붙어 있는 Method는 따로 트랜잭션 처리를 하지 않아도 된다.헉- 결론 : JpaTransacionManager | DatasourceTransactionManager | HibernateTransactionManager 등 사용 가능하다. !코드의 변경 없이!
- 참고 사이트
스프링 캐시
@Cacheable
(@CacheEvit...
등) 를 활용하여 자신의 코드(메소드) 를 변경하지 않고 CacheManager를 적용할 수 있다.
Author And Source
이 문제에 관하여([스프링 입문] 스프링 예제 프로젝트 PetClinic 4), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jinmin2216/스프링-입문-스프링-예제-프로젝트-PetClinic-4저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)