Spring/Spring Database
[Spring Database] 트랜잭션 전파
[Spring Database] 트랜잭션 전파
2022.09.16하나의 메서드 안에서 트랜잭션이 둘 이상 사용되거나, 트랜잭션 내부에서 또 트랜잭션을 거는 경우는 어떻게 처리될까? 하나하나 살펴보자. @Test void double_commit() { log.info("트랜잭션1 시작"); TransactionStatus tx1 = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트랜잭션1 커밋"); txManager.commit(tx1); log.info("트랜잭션2 시작"); TransactionStatus tx2 = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트랜잭션2 커밋"); txManager.co..
[Spring Database] 트랜잭션
[Spring Database] 트랜잭션
2022.09.13데이터 접근 기술들은 트랜잭션을 처리하는 방법이 조금씩 다르다. 따라서 데이터 접근 기술을 바꾸게 되면 트랜잭션을 처리하는 코드들도 모두 바꿔야 한다. 스프링은 PlatformTransactionManager 인터페이스를 통해 트랜잭션 추상화를 제공한다. 인터페이스를 통해 트랜잭션을 사용하면 데이터 접근 기술이 달라져도 동일한 방법으로 트랜잭션을 사용할 수 있다. 많이 사용되는 데이터 접근 기술에 대한 구현체도 함께 제공하고, 사용하는 기술을 인식해 구현체를 스프링 빈으로 등록해준다. 스프링에서는 더 구체적이고 자세한 요소가 더 높은 우선순위를 가진다. 트랜잭션에서도 마찬가지인데, 메서드와 클래스에 @Transactional 애너테이션을 붙일 수 있으면 메서드가 더 높은 우선순위를 가진다. @Spring..
[Spring Database] QueryDSL
[Spring Database] QueryDSL
2022.09.11QueryDSL (Query Domain Specific Language) 특정 도메인에 초점을 맞춘 프로그래밍 언어이다. 쿼리에 특화된 프로그래밍 언어이고, JPA / MongoDB / SQL 같은 데이터베이스 관련 기술들을 사용할 때 쿼리를 type-safe하게 개발 할 수 있게 지원하는 프레임워크이다. Entity 혹은 데이터베이스의 테이블의 정보를 바탕으로 QueryDSL Annotation Processing Tool 를 사용해 쿼리 전용 멤버 객체인 Q(Entity이름).java 를 만든다. (생성된 객체를 바탕으로 쿼리를 자바 코드로 작성한다) 즉, Q().java 파일을 사용해 자바 코드를 작성하고, 작성된 자바 코드는 JQPL로 변환되고 JQPL은 SQL로 변환돼서 실행된다. @Repos..
[Spring Database] Spring Data JPA
[Spring Database] Spring Data JPA
2022.09.11스프링 데이터 JPA 기술의 가장 대표적인 기능은 두 가지이다. 1. 공통 인터페이스 2. 쿼리 메서드 JpaRepository 인터페이스는 기본적인 CRUD 및 공통화가 가능한 기능들을 모두 제공한다. JpaRepository 인터페이스를 사용할 리포지토리에서 상속받고(extends), 제네릭에 관리할 를 입력해주면 스프링 데이터 JPA 기술 내부에서 프록시 기술을 통해 구현 클래스가 생성된다. 만들어진 구현 클래스의 인스턴스는 스프링 빈으로 등록되고, 개발자는 구현 클래스를 신경쓰지 않고 JpaRepository 인터페이스가 제공하는 기술을 사용할 수 있다. 인터페이스에 메서드만 적어두면 스프링 데이터 JPA 기술이 메서드 이름을 분석해 쿼리를 자동으로 만들고 실행해준다. JPA만 사용했을 경우 복잡..
[Spring Database] JPA 적용
[Spring Database] JPA 적용
2022.09.10JPA의 핵심은 객체와 관계형 데이터베이스간의 매핑이다. 애너테이션 기반으로 객체와 데이터베이스를 매핑해보자. @Data @Entity @Table(name = "item") public class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "item_name", length = 10) private String itemName; private Integer price; private Integer quantity; public Item() { } public Item(String itemName, Integer price, Integer quantity) { this.itemN..
[Spring Database] JPA
[Spring Database] JPA
2022.09.09JPA를 사용하기에 앞서 JPA가 도입된 배경에 대해 살펴보자. 애플리케이션을 개발할 때는 Java와 같이 객체지향언어를 사용한다. 또, 데이터베이스는 Oracle / MySQL 과 같은 관계형 데이터베이스를 사용한다. 즉 애플리케이션은 객체로 관리하고, 데이터는 관계형 데이터베이스에 저장한다. 그런데, 데이터베이스는 SQL만 받아들이고 실행할 수 있는데.. 여기서 문제가 발생한다. SQL 반환값을 자바 객체로 변환해야 하고.무엇을 개발하든 SQL에 의존 할 수 밖에 없다. 객체에 멤버 변수가 추가된다면? SQL도 추가된 변수에 따라 모두 수정 해 줘야 한다. 또, 객체지향과 관계형 데이터베이스의 패러다임이 다르다는 문제가 있다. 객체에는 상속이라는 개념이 있어 설계할 때 유용하게 사용할 수 있지만, 테..
[Spring Database] MyBatis
[Spring Database] MyBatis
2022.09.09MyBatis는 JdbcTemplate가 제공하는 대부분의 기능을 제공한다. SQL을 XML을 통해 관리하고, 동적 쿼리 문제를 쉽게 해결할 수 있다는 장점이 있다. 프로젝트에서 동적 쿼리와 복잡한 쿼리가 많이 사용된다면 MyBatis를 사용하는 편이 합리적이고, 단순한 쿼리가 대부분이면 JdbcTemplate을 사용하는 것도 괜찮다. #MyBatis mybatis.type-aliases-package=hello.itemservice.domain mybatis.configuration.map-underscore-to-camel-case=true logging.level.hello.itemservice.repository.mybatis=trace application.properties에 MyBatis 관..
[Spring Database] 데이터베이스 테스트
[Spring Database] 데이터베이스 테스트
2022.09.07데이터베이스를 연동한 상태에서 잘 동작하는지 확인하기 위해 테스트 코드를 작성 해 보자. 우선 test 디렉토리의 application.properties 파일에도 데이터베이스 관련 정보를 넣어 줘야 한다. spring.profiles.active=test spring.datasource.url=jdbc:h2:tcp://localhost/~/test spring.datasource.username=sa logging.level.org.springframework.jdbc=debug @SpringBootTest 애너테이션은 @SpringBootApplication 애너테이션을 찾아서 설정으로 사용한다. 테스트 시 로컬에서 사용하는 데이터베이스가 로컬에서 사용하는 데이터베이스가 겹치면서 테스트에서 문제가 발..
[Spring Database] JdbcTemplate
[Spring Database] JdbcTemplate
2022.09.06SQL을 자바 문자열로 직접 사용할 때 JdbcTemplate을 사용하면 편하다. JdbcTemplate은 spring-jdbc 라이브러리에 기본적으로 포함돼있어 별도의 설정 없이 바로 사용할 수 있고, 템플릿 콜백 패턴을 사용해 JDBC를 직접 사용할 때 발생하는 여러 가지 귀찮은 작업을 대신 처리해준다. (커넥션 획득, 스프링 예외 변환기 실행 등..) /** * jdbc template 구현 */ @Slf4j public class JdbcTemplateItemRepositoryV1 implements ItemRepository { private final JdbcTemplate template; public JdbcTemplateItemRepositoryV1(DataSource dataSource..
[Spring Database] 데이터베이스 예외 처리
[Spring Database] 데이터베이스 예외 처리
2022.09.05서비스가 처리할 수 없는 SQLException 예외를 런타임 예외로 전환하는 방식으로 의존 관계를 제거하자. MemberRepository 클래스도 인터페이스로 변경해 구현 기술을 쉽게 변경할 수 있도록 하자. 이제 MemberService의 코드 변경 없이 DI를 사용해 구현 기술을 변경할 수 있다. 인터페이스의 구현체가 체크 예외를 던지려면 인터페이스의 메서드에 먼저 체크 예외를 던지는 부분이 선언돼있어야 한다. 즉, SQLException과 같이 체크 예외를 사용하는 경우 인터페이스에도 해당 체크 예외가 선언돼있어야 한다. (throws Exception) 그런데, 인터페이스에 throw ~~Exception 문장을 추가하는 순간 해당 인터페이스는 특정 기술에 의존하게 되고, 이건 우리가 의도한 ..
[Spring Database] Transaction AOP
[Spring Database] Transaction AOP
2022.09.01트랜잭션을 적용해 여러 작업들을 하나의 작업으로 묶어서 처리하는건 성공했지만, 비즈니스 로직을 처리하는 코드보다 트랜잭션을 처리하는 코드가 훨씬 더 많아져 코드가 지저분해졌다. 좀 더 간단하게 처리하는 방법을 알아보자. 애플리케이션의 구조는 역할에 따라 세 가지 계층으로 나눌 수 있다. 프레젠테이션 계층 : UI와 관련된 처리를 담당하고, 클라이언트의 요청을 검증하고 응답하는 역할을 한다. (스프링 MVC, HTTP..) 서비스 계층 : 계좌이체와 같은 비즈니스 로직을 담당한다. (특정 기술에 의존하지 않고 자바 코드로 작성) 데이터 접근 계층 : 실제 데이터베이스에 접근하는 코드를 담당한다. (JDBC, JPA...) 모두 중요한 계층이지만, 그 중에서도 핵심 비즈니스 로직이 구현된 서비스 계층은 특히..
[Spring Database] Transaction / Lock
[Spring Database] Transaction / Lock
2022.09.01데이터를 저장할 때 메모장같은 파일이나 다른 저장소 대신 데이터베이스를 사용하는 가장 큰 이유는 데이터베이스가 트랜잭션을 제공하기 때문이다. 데이터베이스에서의 트랜잭션은 한 가지 거래를 안전하게 처리되도록 보장해주는 작업을 의미한다. 인터넷 뱅킹을 생각해보자. A가 B에게 1000원을 이체하면 A의 잔고는 1000만큼 감소시키고, B의 잔고는 1000만큼 증가시켜야 한다. 만약 감소하는 작업은 성공했지만 증가하는 작업은 실패하는 치명적인 오류가 발생한다면? 아무도 그 은행을 사용하지 않을 것이다. 즉, 증가시키는 작업과 감소시키는 작업이 하나의 작업처럼 묶여서 동작해야 한다. 데이터베이스가 제공하는 트랜잭션 기능을 사용하면 두 가지 작업 모두 성공해야 데이터베이스에 값을 저장 (Commit) 하고, 중간..