-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
30a9736
commit 11edfa9
Showing
11 changed files
with
404 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...eactive/HibernateReactiveApplication.java → ...eactive/HibernateReactiveApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
src/main/java/com/example/hibernate/reactive/config/OpenApiConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package com.example.hibernate.reactive.config; | ||
|
||
import io.swagger.v3.core.converter.ModelConverters; | ||
import io.swagger.v3.oas.models.OpenAPI; | ||
import io.swagger.v3.oas.models.SpecVersion; | ||
import io.swagger.v3.oas.models.info.Info; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springdoc.core.GroupedOpenApi; | ||
import org.springdoc.core.providers.ObjectMapperProvider; | ||
import org.springdoc.webflux.core.converters.WebFluxSupportConverter; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
/** | ||
* Open API | ||
*/ | ||
@Configuration | ||
@RequiredArgsConstructor | ||
public class OpenApiConfig { | ||
|
||
private final ObjectMapperProvider objectMapperProvider; | ||
|
||
private static final String WILD_CARD = "/**"; | ||
private static final String API_NAME = "Hibernate-reactive"; | ||
private static final String API_VERSION = "0.0.1"; | ||
private static final String API_DESCRIPTION = "Hibernate-reactive API 명세서"; | ||
|
||
@Bean | ||
public GroupedOpenApi api() { | ||
return GroupedOpenApi.builder() | ||
.group(API_NAME) | ||
.pathsToMatch(WILD_CARD) | ||
.build(); | ||
} | ||
|
||
@Bean | ||
public OpenAPI springShopOpenAPI() { | ||
ModelConverters.getInstance().addConverter(new WebFluxSupportConverter(objectMapperProvider)); | ||
|
||
return new OpenAPI() | ||
.specVersion(SpecVersion.V31) | ||
.info(new Info().title(API_NAME) | ||
.description(API_DESCRIPTION) | ||
.version(API_VERSION)); | ||
} | ||
|
||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/com/example/hibernate/reactive/config/SessionFactoryConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.example.hibernate.reactive.config; | ||
|
||
import org.hibernate.reactive.stage.Stage; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
import javax.persistence.Persistence; | ||
|
||
/** | ||
* 세션 팩토리 설정 | ||
*/ | ||
@Configuration | ||
public class SessionFactoryConfig { | ||
|
||
private static final String PERSISTENCE_UNIT_NAME = "hibernate-reactive-persistence"; | ||
|
||
/** | ||
* 세션 팩토리 반환 | ||
* <p> | ||
* 영속성 단계에서 Stage & Mutiny 존재 | ||
* <p> | ||
* Mutiny Uni 사용한 비동기 인터페이스 | ||
* https://smallrye.io/smallrye-mutiny/1.6.0/#reactive-converters-built-in | ||
* <p> | ||
* Stage CompletionStage 사용한 비동기 인터페이스 | ||
*/ | ||
@Bean | ||
public Stage.SessionFactory sessionFactory() { | ||
return Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME) | ||
.unwrap(Stage.SessionFactory.class); | ||
} | ||
|
||
} |
53 changes: 53 additions & 0 deletions
53
src/main/java/com/example/hibernate/reactive/domain/customer/Customer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.example.hibernate.reactive.domain.customer; | ||
|
||
import com.example.hibernate.reactive.enums.SexType; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
import javax.persistence.Column; | ||
import javax.persistence.Entity; | ||
import javax.persistence.EnumType; | ||
import javax.persistence.Enumerated; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.Id; | ||
import javax.persistence.Table; | ||
import javax.validation.constraints.Max; | ||
import javax.validation.constraints.Min; | ||
import javax.validation.constraints.NotNull; | ||
import javax.validation.constraints.Size; | ||
|
||
/** | ||
* 테스트용 테이블 | ||
*/ | ||
@Table | ||
@Entity | ||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class Customer { | ||
|
||
@Id | ||
@GeneratedValue | ||
private Integer id; | ||
|
||
@NotNull | ||
@Size(max = 100) | ||
@Column(unique = true, length = 100) | ||
private String name; | ||
|
||
@Column(length = 30) | ||
@Enumerated(value = EnumType.STRING) | ||
private SexType sex; | ||
|
||
@Column | ||
@Min(value = 18) | ||
@Max(value = 70) | ||
private Integer age; | ||
|
||
public Customer(String name, SexType sex, Integer age) { | ||
this.name = name; | ||
this.sex = sex; | ||
this.age = age; | ||
} | ||
|
||
} |
48 changes: 48 additions & 0 deletions
48
src/main/java/com/example/hibernate/reactive/domain/customer/CustomerController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package com.example.hibernate.reactive.domain.customer; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.PutMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import reactor.core.publisher.Mono; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@Tag(name = "고객 Controller") | ||
@RequestMapping(value = "/customer") | ||
public class CustomerController { | ||
|
||
private final CustomerService customerService; | ||
|
||
@Operation(summary = "고객 조회") | ||
@GetMapping(value = "/{name}") | ||
public Mono<CustomerDto> getCustomer(@PathVariable String name) throws InterruptedException { | ||
return customerService.getCustomer(name); | ||
} | ||
|
||
@PostMapping | ||
@Operation(summary = "고객 등록") | ||
public Mono<Void> save(@RequestBody CustomerDto customerDto) { | ||
return customerService.save(customerDto); | ||
} | ||
|
||
@PutMapping | ||
@Operation(summary = "고객 업데이트") | ||
public Mono<Integer> update(@RequestBody CustomerDto customerDto) { | ||
return customerService.update(customerDto); | ||
} | ||
|
||
@Operation(summary = "고객 삭제") | ||
@DeleteMapping(value = "/{name}") | ||
public Mono<Integer> delete(@PathVariable String name) { | ||
return customerService.delete(name); | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/com/example/hibernate/reactive/domain/customer/CustomerDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.example.hibernate.reactive.domain.customer; | ||
|
||
import com.example.hibernate.reactive.enums.SexType; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
|
||
import javax.validation.constraints.NotNull; | ||
|
||
@Schema(description = "고객 객체") | ||
public record CustomerDto( | ||
@Schema(description = "이름", example = "이진원") @NotNull String name, | ||
@Schema(description = "성별") @NotNull SexType sex, | ||
@Schema(description = "나이", example = "28") @NotNull Integer age) { | ||
} |
79 changes: 79 additions & 0 deletions
79
src/main/java/com/example/hibernate/reactive/domain/customer/CustomerRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.example.hibernate.reactive.domain.customer; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.hibernate.reactive.stage.Stage; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.util.concurrent.CompletableFuture; | ||
|
||
/** | ||
* 고객 Repository | ||
*/ | ||
@Repository | ||
@RequiredArgsConstructor | ||
public class CustomerRepository { | ||
|
||
private final Stage.SessionFactory sessionFactory; | ||
|
||
private static final String NAME = "name"; | ||
private static final String SEX = "sex"; | ||
private static final String AGE = "age"; | ||
|
||
/** | ||
* 고객 저장 | ||
* | ||
* @param customer 고객 | ||
* @return CompletableFuture<Void> | ||
*/ | ||
public CompletableFuture<Void> save(Customer customer) { | ||
return sessionFactory.withTransaction( | ||
(session, transaction) -> session.persist(customer) | ||
).toCompletableFuture(); | ||
} | ||
|
||
/** | ||
* 고객 조회 | ||
* | ||
* @param name 이름 | ||
* @return CompletableFuture<Customer> | ||
*/ | ||
public CompletableFuture<Customer> get(String name) { | ||
return sessionFactory.withSession( | ||
session -> session.createQuery("from Customer where name=:name order by name", Customer.class) | ||
.setParameter(NAME, name) | ||
.getSingleResult() | ||
).toCompletableFuture(); | ||
} | ||
|
||
/** | ||
* 고객 업데이트 | ||
* | ||
* @param customer 고객 | ||
* @return CompletableFuture<Integer> | ||
*/ | ||
public CompletableFuture<Integer> update(Customer customer) { | ||
return sessionFactory.withTransaction( | ||
session -> session | ||
.createQuery("update Customer set name=:name, sex=:sex, age=:age where name=:name") | ||
.setParameter(NAME, customer.getName()) | ||
.setParameter(SEX, customer.getSex()) | ||
.setParameter(AGE, customer.getAge()) | ||
.executeUpdate() | ||
).toCompletableFuture(); | ||
} | ||
|
||
/** | ||
* 고객 삭제 | ||
* | ||
* @param name 이름 | ||
* @return CompletableFuture<Integer> | ||
*/ | ||
public CompletableFuture<Integer> delete(String name) { | ||
return sessionFactory.withTransaction( | ||
session -> session.createQuery("delete Customer where name=:name") | ||
.setParameter(NAME, name) | ||
.executeUpdate() | ||
).toCompletableFuture(); | ||
} | ||
|
||
} |
69 changes: 69 additions & 0 deletions
69
src/main/java/com/example/hibernate/reactive/domain/customer/CustomerService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.example.hibernate.reactive.domain.customer; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
import reactor.core.publisher.Mono; | ||
|
||
@Slf4j | ||
@Service | ||
@AllArgsConstructor | ||
public class CustomerService { | ||
|
||
private final CustomerRepository customerRepository; | ||
|
||
private static final String DELETE_CUSTOMER_FORMAT = "{} 고객 정보 : {} 삭제 완료"; | ||
private static final String POST_CUSTOMER_INFO = "고객 이름 : {} 저장 완료"; | ||
private static final String UPDATE_CUSTOMER_INFO = "{} 고객 업데이트 완료"; | ||
|
||
/** | ||
* 고객 조회 | ||
* | ||
* @param name 이름 | ||
*/ | ||
public Mono<CustomerDto> getCustomer(String name) { | ||
var customerCf = customerRepository.get(name); | ||
return Mono.fromFuture(customerCf) | ||
.cast(Customer.class) | ||
.map(customer -> new CustomerDto(customer.getName(), customer.getSex(), customer.getAge())); | ||
} | ||
|
||
/** | ||
* 고객 저장 | ||
* | ||
* @param customerDto 고객 객체 | ||
*/ | ||
public Mono<Void> save(CustomerDto customerDto) { | ||
var customer = new Customer(customerDto.name(), customerDto.sex(), customerDto.age()); | ||
var cfInsert = customerRepository.save(customer); | ||
return Mono.fromFuture(cfInsert) | ||
.cast(Void.class) | ||
.doOnNext(v -> log.info(POST_CUSTOMER_INFO, customer.getName())); | ||
} | ||
|
||
/** | ||
* 고객 업데이트 | ||
* | ||
* @param customerDto 고객 객체 | ||
*/ | ||
public Mono<Integer> update(CustomerDto customerDto) { | ||
var customer = new Customer(customerDto.name(), customerDto.sex(), customerDto.age()); | ||
var updateCf = customerRepository.update(customer); | ||
return Mono.fromFuture(updateCf) | ||
.cast(Integer.class) | ||
.doOnNext(info -> log.info(UPDATE_CUSTOMER_INFO, info)); | ||
} | ||
|
||
/** | ||
* 고객 삭제 | ||
* | ||
* @param name 이름 | ||
*/ | ||
public Mono<Integer> delete(String name) { | ||
var deleteCf = customerRepository.delete(name); | ||
return Mono.fromFuture(deleteCf) | ||
.cast(Integer.class) | ||
.doOnNext(info -> log.info(DELETE_CUSTOMER_FORMAT, info, name)); | ||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/example/hibernate/reactive/enums/SexType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.example.hibernate.reactive.enums; | ||
|
||
/** | ||
* 성별 타입 | ||
*/ | ||
public enum SexType { | ||
|
||
MALE, | ||
FEMALE, | ||
} |
Oops, something went wrong.