마이크로서비스를 구축할 첫 서비스는 account 서비스입니다. 계좌 관련 서비스라고 생각하면 됩니다. 먼저 프로젝트를 생성하도록 하겠습니다. IntelliJ 에 포함된 프로젝트 생성기를 통해 시작해보도록 하겠습니다.
화면에 보이는 것과 같이 dependencies를 추가해줍니다.
그 다음 프로젝트를 열고 application.yml 파일을 작성하겠습니다.
server: port: 8080 spring: datasource: url: jdbc:h2:mem:testdb driverClassName: org.h2.Driver username: sa password: '' h2: console: enabled: true jpa: database-platform: org.hibernate.dialect.H2Dialect hibernate: ddl-auto: update show-sql: true
다음으론 DB 테이블을 생성하도록 schema.sql을 작성하겠습니다.
CREATE TABLE IF NOT EXISTS `customer` (
`customer_id` int AUTO_INCREMENT PRIMARY KEY,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`mobile_number` varchar(20) NOT NULL,
`created_at` date NOT NULL,
`created_by` varchar(20) NOT NULL,
`updated_at` date DEFAULT NULL,
`updated_by` varchar(20) DEFAULT NULL
);
CREATE TABLE IF NOT EXISTS `account` (
`customer_id` int NOT NULL,
`account_number` int AUTO_INCREMENT PRIMARY KEY,
`account_type` varchar(100) NOT NULL,
`branch_address` varchar(200) NOT NULL,
`created_at` date NOT NULL,
`created_by` varchar(20) NOT NULL,
`updated_at` date DEFAULT NULL,
`updated_by` varchar(20) DEFAULT NULL
);
다음으로 Spring Data JPA를 활용해 DB 테이블과 연동할 수 있도록 엔티티와 레포지토리 코드를 작성하겠습니다.
앞으로 만들 엔티티는 Account와 Customer 엔티티 클래스와 이 둘 클래스가 모두 공통으로 포함하고 있는 BaseEntity 클래스입니다.
BaseEntity라는 클래스를 생성하고, 이 클래스에 데이터베이스의 메타데이터 컬럼을 표현하는 필드를 정의합니다. 이 클래스는 다른 엔티티 클래스들이 상속받아 사용할 수 있도록 합니다. BaseEntity 클래스에는 createdAt, createdBy, updatedAt, updatedBy라는 네 가지 필드가 있으며, 각각의 필드는 데이터베이스의 컬럼과 매핑됩니다. Lombok 라이브러리를 사용하여 getter, setter, toString 메서드를 자동으로 생성하고, 이를 위한 어노테이션을 클래스에 추가합니다.
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Getter @Setter @ToString
public class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdAt;
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedDate
@Column(insertable = false)
private LocalDateTime updatedAt;
@LastModifiedBy
@Column(insertable = false)
private String updatedBy;
}
BaseEntity 클래스를 상속받는 Customer 클래스에는 customerID, name, email, mobileNumber 필드가 있으며, 이 필드들은 데이터베이스 테이블의 컬럼과 매핑됩니다. customerID는 기본 키로 설정되며, 이를 위해 @Id 및 @GeneratedValue 어노테이션을 사용합니다.
@Entity
@Getter @Setter @ToString @AllArgsConstructor @NoArgsConstructor
public class Customer extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="customer_id")
private Long customerId;
private String name;
private String email;
@Column(name="mobile_number")
private String mobileNumber;
}
BaseEntity 클래스를 상속받는 Account 클래스에는 accountNumber, accountType, branchAddress 필드가 있으며, accountNumber가 기본 키로 설정됩니다.
@Entity
@Getter @Setter @ToString @AllArgsConstructor @NoArgsConstructor
public class Customer extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="customer_id")
private Long customerId;
private String name;
private String email;
@Column(name="mobile_number")
private String mobileNumber;
}
엔티티 클래스를 모두 생성한 후에는 엔티티 클래스와 데이터베이스 테이블 간의 상호작용을 위해 Repository 인터페이스를 생성합니다. CustomerRepository와 AccountRepository라는 두 개의 인터페이스를 생성하고, 이들 인터페이스는 Spring Data JPA의 JpaRepository를 확장합니다. 이를 통해 CRUD(생성, 읽기, 갱신, 삭제) 작업을 위한 메서드를 자동으로 제공받을 수 있습니다. JpaRepository는 제네릭 타입으로 엔티티 클래스와 그 기본 키의 데이터 타입을 받으며, 이로 인해 개발자는 별도의 SQL을 작성하지 않고도 데이터베이스 작업을 수행할 수 있습니다.
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {
Optional<Customer> findByMobileNumber(String mobileNumber);
}
@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {
Optional<Account> findByCustomerId(Long customerId);
@Transactional
@Modifying
void deleteByCustomerId(Long customerId);
}
이제 엔티티 클래스와 리포지토리 인터페이스를 모두 생성하였으므로, 데이터베이스와 상호작용하는 방법을 다루는 다음 스텝으로 넘어갈 준비가 되었습니다.