From dc9b40e78b4f9bc3e6ed759b57ce29b257bad996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dean=5B=EB=B0=B1=EB=B3=91=EB=82=A8=5D?= Date: Mon, 17 Nov 2025 14:19:29 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=93=A4=EC=97=AC=EC=93=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 21 +- .../cd/kamcoback/KamcoBackApplication.java | 6 +- .../common/api/HelloApiController.java | 14 +- .../cd/kamcoback/common/api/HelloDto.java | 40 ++-- .../common/service/BaseCoreService.java | 40 ++-- .../common/service/HelloService.java | 10 +- .../utils/geometry/GeometryDeserializer.java | 38 ++-- .../utils/geometry/GeometrySerializer.java | 32 +-- .../cd/kamcoback/config/StartupLogger.java | 88 ++++---- .../kamco/cd/kamcoback/config/WebConfig.java | 22 +- .../kamcoback/config/api/ApiResponseDto.java | 202 +++++++++--------- .../cd/kamcoback/config/enums/EnumType.java | 4 +- .../kamcoback/postgres/CommonDateEntity.java | 30 +-- .../cd/kamcoback/postgres/QueryDslConfig.java | 10 +- .../postgres/core/AnimalCoreService.java | 104 +++++---- .../postgres/core/ZooCoreService.java | 107 +++++----- .../postgres/entity/AnimalEntity.java | 72 +++---- .../kamcoback/postgres/entity/ZooEntity.java | 62 +++--- .../postgres/repository/AnimalRepository.java | 2 +- .../repository/AnimalRepositoryCustom.java | 6 +- .../repository/AnimalRepositoryImpl.java | 143 ++++++------- .../repository/ZooRepositoryCustom.java | 8 +- .../repository/ZooRepositoryImpl.java | 104 +++++---- .../cd/kamcoback/zoo/AnimalApiController.java | 120 +++++------ .../cd/kamcoback/zoo/ZooApiController.java | 18 +- .../kamco/cd/kamcoback/zoo/dto/AnimalDto.java | 71 +++--- .../kamco/cd/kamcoback/zoo/dto/ZooDto.java | 49 ++--- .../cd/kamcoback/zoo/service/ZooService.java | 85 ++++---- .../kamcoback/KamcoBackApplicationTests.java | 4 +- 29 files changed, 735 insertions(+), 777 deletions(-) diff --git a/build.gradle b/build.gradle index c9b56701..ece8e565 100644 --- a/build.gradle +++ b/build.gradle @@ -60,30 +60,13 @@ bootJar { archiveFileName = 'ROOT.jar' } -// Spotless configuration for code formatting -//spotless { -// java { -// target 'src/**/*.java' -// googleJavaFormat('1.19.2').aosp().reflowLongStrings() -// indentWithSpaces(2) -// trimTrailingWhitespace() -// endWithNewline() -// importOrder() -// removeUnusedImports() -// formatAnnotations() -// } -//} - - +// Spotless configuration for code formatting (2-space indent) spotless { java { target 'src/**/*.java' - indentWithSpaces(2) + googleJavaFormat('1.19.2') // Default Google Style = 2 spaces (NO .aosp()!) trimTrailingWhitespace() endWithNewline() - importOrder() - removeUnusedImports() - formatAnnotations() } } diff --git a/src/main/java/com/kamco/cd/kamcoback/KamcoBackApplication.java b/src/main/java/com/kamco/cd/kamcoback/KamcoBackApplication.java index 6ac3c950..c03ed73d 100644 --- a/src/main/java/com/kamco/cd/kamcoback/KamcoBackApplication.java +++ b/src/main/java/com/kamco/cd/kamcoback/KamcoBackApplication.java @@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class KamcoBackApplication { - public static void main(String[] args) { - SpringApplication.run(KamcoBackApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(KamcoBackApplication.class, args); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/common/api/HelloApiController.java b/src/main/java/com/kamco/cd/kamcoback/common/api/HelloApiController.java index 2553dfec..d8dcb066 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/api/HelloApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/api/HelloApiController.java @@ -12,14 +12,14 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/api/hello") public class HelloApiController { - private final HelloService helloService; + private final HelloService helloService; - @GetMapping - public HelloDto.Res hello(HelloDto.Req req) { - req.valid(); + @GetMapping + public HelloDto.Res hello(HelloDto.Req req) { + req.valid(); - Res res = helloService.sayHello(req); + Res res = helloService.sayHello(req); - return res; - } + return res; + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/common/api/HelloDto.java b/src/main/java/com/kamco/cd/kamcoback/common/api/HelloDto.java index 58375271..f7668196 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/api/HelloDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/api/HelloDto.java @@ -8,29 +8,29 @@ import lombok.Setter; public class HelloDto { - @Getter - @Setter - @NoArgsConstructor - @AllArgsConstructor - public static class Req { - private String id; + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class Req { + private String id; - public void valid() { - if (id == null) { - throw new IllegalArgumentException(id); - } - } + public void valid() { + if (id == null) { + throw new IllegalArgumentException(id); + } } + } - @Getter - public static class Res { - private String id; - private String name; + @Getter + public static class Res { + private String id; + private String name; - @Builder - public Res(String id, String name) { - this.id = id; - this.name = name; - } + @Builder + public Res(String id, String name) { + this.id = id; + this.name = name; } + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/common/service/BaseCoreService.java b/src/main/java/com/kamco/cd/kamcoback/common/service/BaseCoreService.java index cc583e5a..072e8081 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/service/BaseCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/service/BaseCoreService.java @@ -13,26 +13,26 @@ import org.springframework.data.domain.Page; */ public interface BaseCoreService { - /** - * ID로 엔티티를 삭제합니다. - * - * @param id 삭제할 엔티티의 ID - */ - void remove(ID id); + /** + * ID로 엔티티를 삭제합니다. + * + * @param id 삭제할 엔티티의 ID + */ + void remove(ID id); - /** - * ID로 단건 조회합니다. - * - * @param id 조회할 엔티티의 ID - * @return 조회된 엔티티 - */ - T getOneById(ID id); + /** + * ID로 단건 조회합니다. + * + * @param id 조회할 엔티티의 ID + * @return 조회된 엔티티 + */ + T getOneById(ID id); - /** - * 검색 조건과 페이징으로 조회합니다. - * - * @param searchReq 검색 조건 - * @return 페이징 처리된 검색 결과 - */ - Page search(S searchReq); + /** + * 검색 조건과 페이징으로 조회합니다. + * + * @param searchReq 검색 조건 + * @return 페이징 처리된 검색 결과 + */ + Page search(S searchReq); } diff --git a/src/main/java/com/kamco/cd/kamcoback/common/service/HelloService.java b/src/main/java/com/kamco/cd/kamcoback/common/service/HelloService.java index e7b0ce3e..a3b4b4f5 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/service/HelloService.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/service/HelloService.java @@ -9,9 +9,9 @@ import org.springframework.stereotype.Service; @Service public class HelloService { - public HelloDto.Res sayHello(HelloDto.Req req) { - log.info("hello"); - String name = UUID.randomUUID().toString(); - return HelloDto.Res.builder().id(req.getId()).name(name).build(); - } + public HelloDto.Res sayHello(HelloDto.Req req) { + log.info("hello"); + String name = UUID.randomUUID().toString(); + return HelloDto.Res.builder().id(req.getId()).name(name).build(); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java index aa536dd9..ee14b8d5 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java @@ -11,26 +11,26 @@ import org.springframework.util.StringUtils; public class GeometryDeserializer extends StdDeserializer { - public GeometryDeserializer(Class targetType) { - super(targetType); + public GeometryDeserializer(Class targetType) { + super(targetType); + } + + // TODO: test code + @SuppressWarnings("unchecked") + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + String json = jsonParser.readValueAsTree().toString(); + + if (!StringUtils.hasText(json)) { + return null; } - // TODO: test code - @SuppressWarnings("unchecked") - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException, JacksonException { - String json = jsonParser.readValueAsTree().toString(); - - if (!StringUtils.hasText(json)) { - return null; - } - - try { - GeoJsonReader reader = new GeoJsonReader(); - return (T) reader.read(json); - } catch (Exception e) { - throw new IllegalArgumentException("Failed to deserialize GeoJSON into Geometry", e); - } + try { + GeoJsonReader reader = new GeoJsonReader(); + return (T) reader.read(json); + } catch (Exception e) { + throw new IllegalArgumentException("Failed to deserialize GeoJSON into Geometry", e); } + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java index 50b7abb3..733c36a0 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java @@ -10,22 +10,22 @@ import org.locationtech.jts.io.geojson.GeoJsonWriter; public class GeometrySerializer extends StdSerializer { - // TODO: test code - public GeometrySerializer(Class targetType) { - super(targetType); - } + // TODO: test code + public GeometrySerializer(Class targetType) { + super(targetType); + } - @Override - public void serialize( - T geometry, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) - throws IOException { - if (Objects.nonNull(geometry)) { - // default: 8자리 강제로 반올림시킴. 16자리로 늘려줌 - GeoJsonWriter writer = new GeoJsonWriter(16); - String json = writer.write(geometry); - jsonGenerator.writeRawValue(json); - } else { - jsonGenerator.writeNull(); - } + @Override + public void serialize( + T geometry, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) + throws IOException { + if (Objects.nonNull(geometry)) { + // default: 8자리 강제로 반올림시킴. 16자리로 늘려줌 + GeoJsonWriter writer = new GeoJsonWriter(16); + String json = writer.write(geometry); + jsonGenerator.writeRawValue(json); + } else { + jsonGenerator.writeNull(); } + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/config/StartupLogger.java b/src/main/java/com/kamco/cd/kamcoback/config/StartupLogger.java index 178f5201..4df4c837 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/StartupLogger.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/StartupLogger.java @@ -14,49 +14,47 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class StartupLogger { - private final Environment environment; - private final DataSource dataSource; + private final Environment environment; + private final DataSource dataSource; - @EventListener(ApplicationReadyEvent.class) - public void logStartupInfo() { - String[] activeProfiles = environment.getActiveProfiles(); - String profileInfo = - activeProfiles.length > 0 ? String.join(", ", activeProfiles) : "default"; + @EventListener(ApplicationReadyEvent.class) + public void logStartupInfo() { + String[] activeProfiles = environment.getActiveProfiles(); + String profileInfo = activeProfiles.length > 0 ? String.join(", ", activeProfiles) : "default"; - // Database connection information - String dbUrl = environment.getProperty("spring.datasource.url"); - String dbUsername = environment.getProperty("spring.datasource.username"); - String dbDriver = environment.getProperty("spring.datasource.driver-class-name"); + // Database connection information + String dbUrl = environment.getProperty("spring.datasource.url"); + String dbUsername = environment.getProperty("spring.datasource.username"); + String dbDriver = environment.getProperty("spring.datasource.driver-class-name"); - // HikariCP pool settings - String poolInfo = ""; - if (dataSource instanceof HikariDataSource hikariDs) { - poolInfo = - String.format( - """ + // HikariCP pool settings + String poolInfo = ""; + if (dataSource instanceof HikariDataSource hikariDs) { + poolInfo = + String.format( + """ │ Pool Size : min=%d, max=%d │ Connection Timeout: %dms │ Idle Timeout : %dms │ Max Lifetime : %dms""", - hikariDs.getMinimumIdle(), - hikariDs.getMaximumPoolSize(), - hikariDs.getConnectionTimeout(), - hikariDs.getIdleTimeout(), - hikariDs.getMaxLifetime()); - } + hikariDs.getMinimumIdle(), + hikariDs.getMaximumPoolSize(), + hikariDs.getConnectionTimeout(), + hikariDs.getIdleTimeout(), + hikariDs.getMaxLifetime()); + } - // JPA/Hibernate settings - String showSql = environment.getProperty("spring.jpa.show-sql", "false"); - String ddlAuto = environment.getProperty("spring.jpa.hibernate.ddl-auto", "none"); - String batchSize = - environment.getProperty("spring.jpa.properties.hibernate.jdbc.batch_size", "N/A"); - String batchFetchSize = - environment.getProperty( - "spring.jpa.properties.hibernate.default_batch_fetch_size", "N/A"); + // JPA/Hibernate settings + String showSql = environment.getProperty("spring.jpa.show-sql", "false"); + String ddlAuto = environment.getProperty("spring.jpa.hibernate.ddl-auto", "none"); + String batchSize = + environment.getProperty("spring.jpa.properties.hibernate.jdbc.batch_size", "N/A"); + String batchFetchSize = + environment.getProperty("spring.jpa.properties.hibernate.default_batch_fetch_size", "N/A"); - String startupMessage = - String.format( - """ + String startupMessage = + String.format( + """ ╔════════════════════════════════════════════════════════════════════════════════╗ ║ 🚀 APPLICATION STARTUP INFORMATION ║ @@ -83,16 +81,16 @@ public class StartupLogger { │ Fetch Batch Size : %s ╚════════════════════════════════════════════════════════════════════════════════╝ """, - profileInfo, - dbUrl != null ? dbUrl : "N/A", - dbUsername != null ? dbUsername : "N/A", - dbDriver != null ? dbDriver : "PostgreSQL JDBC Driver (auto-detected)", - poolInfo, - showSql, - ddlAuto, - batchSize, - batchFetchSize); + profileInfo, + dbUrl != null ? dbUrl : "N/A", + dbUsername != null ? dbUsername : "N/A", + dbDriver != null ? dbDriver : "PostgreSQL JDBC Driver (auto-detected)", + poolInfo, + showSql, + ddlAuto, + batchSize, + batchFetchSize); - log.info(startupMessage); - } + log.info(startupMessage); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java index f20fd274..1b8efc7a 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java @@ -14,18 +14,18 @@ import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class WebConfig { - @Bean - public ObjectMapper objectMapper() { - SimpleModule module = new SimpleModule(); - module.addSerializer(Geometry.class, new GeometrySerializer<>(Geometry.class)); - module.addDeserializer(Geometry.class, new GeometryDeserializer<>(Geometry.class)); + @Bean + public ObjectMapper objectMapper() { + SimpleModule module = new SimpleModule(); + module.addSerializer(Geometry.class, new GeometrySerializer<>(Geometry.class)); + module.addDeserializer(Geometry.class, new GeometryDeserializer<>(Geometry.class)); - module.addSerializer(Polygon.class, new GeometrySerializer<>(Polygon.class)); - module.addDeserializer(Polygon.class, new GeometryDeserializer<>(Polygon.class)); + module.addSerializer(Polygon.class, new GeometrySerializer<>(Polygon.class)); + module.addDeserializer(Polygon.class, new GeometryDeserializer<>(Polygon.class)); - module.addSerializer(Point.class, new GeometrySerializer<>(Point.class)); - module.addDeserializer(Point.class, new GeometryDeserializer<>(Point.class)); + module.addSerializer(Point.class, new GeometrySerializer<>(Point.class)); + module.addDeserializer(Point.class, new GeometryDeserializer<>(Point.class)); - return Jackson2ObjectMapperBuilder.json().modulesToInstall(module).build(); - } + return Jackson2ObjectMapperBuilder.json().modulesToInstall(module).build(); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseDto.java b/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseDto.java index 49f7e413..eac190c4 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseDto.java @@ -10,111 +10,111 @@ import lombok.ToString; @ToString public class ApiResponseDto { - private T data; + private T data; - @JsonInclude(JsonInclude.Include.NON_NULL) - private Error error; + @JsonInclude(JsonInclude.Include.NON_NULL) + private Error error; - @JsonInclude(JsonInclude.Include.NON_NULL) - private T errorData; + @JsonInclude(JsonInclude.Include.NON_NULL) + private T errorData; - public ApiResponseDto(T data) { - this.data = data; + public ApiResponseDto(T data) { + this.data = data; + } + + public ApiResponseDto(ApiResponseCode code) { + this.error = new Error(code.getId(), code.getMessage()); + } + + public ApiResponseDto(ApiResponseCode code, String message) { + this.error = new Error(code.getId(), message); + } + + public ApiResponseDto(ApiResponseCode code, String message, T errorData) { + this.error = new Error(code.getId(), message); + this.errorData = errorData; + } + + public static ApiResponseDto createOK(T data) { + return new ApiResponseDto<>(data); + } + + public static ApiResponseDto createException(ApiResponseCode code) { + return new ApiResponseDto<>(code); + } + + public static ApiResponseDto createException(ApiResponseCode code, String message) { + return new ApiResponseDto<>(code, message); + } + + public static ApiResponseDto createException( + ApiResponseCode code, String message, T data) { + return new ApiResponseDto<>(code, message, data); + } + + @Getter + public static class Error { + + private final String code; + private final String message; + + public Error(String code, String message) { + this.code = code; + this.message = message; + } + } + + @Getter + @RequiredArgsConstructor + public enum ApiResponseCode implements EnumType { + + // @formatter:off + OK("요청이 성공하였습니다."), + BAD_REQUEST("요청 파라미터가 잘못되었습니다."), + ALREADY_EXIST_MALL("이미 등록된 쇼핑센터입니다."), + NOT_FOUND_MAP("지도를 찾을 수 없습니다."), + UNAUTHORIZED("권한이 없습니다."), + CONFLICT("이미 등록된 컨텐츠입니다."), + NOT_FOUND("Resource를 찾을 수 없습니다."), + NOT_FOUND_DATA("데이터를 찾을 수 없습니다."), + NOT_FOUND_WEATHER_DATA("날씨 데이터를 찾을 수 없습니다."), + FAIL_SEND_MESSAGE("메시지를 전송하지 못했습니다."), + TOO_MANY_CONNECTED_MACHINES("연결된 기기가 너무 많습니다."), + UNAUTHENTICATED("인증에 실패하였습니다."), + INVALID_TOKEN("잘못된 토큰입니다."), + EXPIRED_TOKEN("만료된 토큰입니다."), + INTERNAL_SERVER_ERROR("서버에 문제가 발생 하였습니다."), + FORBIDDEN("권한을 확인해주세요."), + INVALID_PASSWORD("잘못된 비밀번호 입니다."), + NOT_FOUND_CAR_IN("입차정보가 없습니다."), + WRONG_STATUS("잘못된 상태입니다."), + FAIL_VERIFICATION("인증에 실패하였습니다."), + INVALID_EMAIL("잘못된 형식의 이메일입니다."), + REQUIRED_EMAIL("이메일은 필수 항목입니다."), + WRONG_PASSWORD("잘못된 패스워드입니다.."), + DUPLICATE_EMAIL("이미 가입된 이메일입니다."), + DUPLICATE_DATA("이미 등록되여 있습니다."), + DATA_INTEGRITY_ERROR("요청을 처리할수 없습니다."), + FOREIGN_KEY_ERROR("참조 중인 데이터가 있어 삭제할 수 없습니다."), + DUPLICATE_EMPLOYEEID("이미 가입된 사번입니다."), + NOT_FOUND_USER_FOR_EMAIL("이메일로 유저를 찾을 수 없습니다."), + NOT_FOUND_USER("사용자를 찾을 수 없습니다."), + INVALID_EMAIL_TOKEN( + "You can only reset your password within 24 hours from when the email was sent.\n" + + "To reset your password again, please submit a new request through \"Forgot" + + " Password.\""), + ; + // @formatter:on + private final String message; + + @Override + public String getId() { + return name(); } - public ApiResponseDto(ApiResponseCode code) { - this.error = new Error(code.getId(), code.getMessage()); - } - - public ApiResponseDto(ApiResponseCode code, String message) { - this.error = new Error(code.getId(), message); - } - - public ApiResponseDto(ApiResponseCode code, String message, T errorData) { - this.error = new Error(code.getId(), message); - this.errorData = errorData; - } - - public static ApiResponseDto createOK(T data) { - return new ApiResponseDto<>(data); - } - - public static ApiResponseDto createException(ApiResponseCode code) { - return new ApiResponseDto<>(code); - } - - public static ApiResponseDto createException(ApiResponseCode code, String message) { - return new ApiResponseDto<>(code, message); - } - - public static ApiResponseDto createException( - ApiResponseCode code, String message, T data) { - return new ApiResponseDto<>(code, message, data); - } - - @Getter - public static class Error { - - private final String code; - private final String message; - - public Error(String code, String message) { - this.code = code; - this.message = message; - } - } - - @Getter - @RequiredArgsConstructor - public enum ApiResponseCode implements EnumType { - - // @formatter:off - OK("요청이 성공하였습니다."), - BAD_REQUEST("요청 파라미터가 잘못되었습니다."), - ALREADY_EXIST_MALL("이미 등록된 쇼핑센터입니다."), - NOT_FOUND_MAP("지도를 찾을 수 없습니다."), - UNAUTHORIZED("권한이 없습니다."), - CONFLICT("이미 등록된 컨텐츠입니다."), - NOT_FOUND("Resource를 찾을 수 없습니다."), - NOT_FOUND_DATA("데이터를 찾을 수 없습니다."), - NOT_FOUND_WEATHER_DATA("날씨 데이터를 찾을 수 없습니다."), - FAIL_SEND_MESSAGE("메시지를 전송하지 못했습니다."), - TOO_MANY_CONNECTED_MACHINES("연결된 기기가 너무 많습니다."), - UNAUTHENTICATED("인증에 실패하였습니다."), - INVALID_TOKEN("잘못된 토큰입니다."), - EXPIRED_TOKEN("만료된 토큰입니다."), - INTERNAL_SERVER_ERROR("서버에 문제가 발생 하였습니다."), - FORBIDDEN("권한을 확인해주세요."), - INVALID_PASSWORD("잘못된 비밀번호 입니다."), - NOT_FOUND_CAR_IN("입차정보가 없습니다."), - WRONG_STATUS("잘못된 상태입니다."), - FAIL_VERIFICATION("인증에 실패하였습니다."), - INVALID_EMAIL("잘못된 형식의 이메일입니다."), - REQUIRED_EMAIL("이메일은 필수 항목입니다."), - WRONG_PASSWORD("잘못된 패스워드입니다.."), - DUPLICATE_EMAIL("이미 가입된 이메일입니다."), - DUPLICATE_DATA("이미 등록되여 있습니다."), - DATA_INTEGRITY_ERROR("요청을 처리할수 없습니다."), - FOREIGN_KEY_ERROR("참조 중인 데이터가 있어 삭제할 수 없습니다."), - DUPLICATE_EMPLOYEEID("이미 가입된 사번입니다."), - NOT_FOUND_USER_FOR_EMAIL("이메일로 유저를 찾을 수 없습니다."), - NOT_FOUND_USER("사용자를 찾을 수 없습니다."), - INVALID_EMAIL_TOKEN( - "You can only reset your password within 24 hours from when the email was sent.\n" - + "To reset your password again, please submit a new request through \"Forgot" - + " Password.\""), - ; - // @formatter:on - private final String message; - - @Override - public String getId() { - return name(); - } - - @Override - public String getText() { - return message; - } + @Override + public String getText() { + return message; } + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/config/enums/EnumType.java b/src/main/java/com/kamco/cd/kamcoback/config/enums/EnumType.java index 7531f0ff..274bfe72 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/enums/EnumType.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/enums/EnumType.java @@ -2,7 +2,7 @@ package com.kamco.cd.kamcoback.config.enums; public interface EnumType { - String getId(); + String getId(); - String getText(); + String getText(); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/CommonDateEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/CommonDateEntity.java index b2914860..9d230de1 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/CommonDateEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/CommonDateEntity.java @@ -13,22 +13,22 @@ import org.springframework.data.annotation.LastModifiedDate; @MappedSuperclass public class CommonDateEntity { - @CreatedDate - @Column(name = "created_date", updatable = false, nullable = false) - private ZonedDateTime createdDate; + @CreatedDate + @Column(name = "created_date", updatable = false, nullable = false) + private ZonedDateTime createdDate; - @LastModifiedDate - @Column(name = "modified_date", nullable = false) - private ZonedDateTime modifiedDate; + @LastModifiedDate + @Column(name = "modified_date", nullable = false) + private ZonedDateTime modifiedDate; - @PrePersist - protected void onPersist() { - this.createdDate = ZonedDateTime.now(); - this.modifiedDate = ZonedDateTime.now(); - } + @PrePersist + protected void onPersist() { + this.createdDate = ZonedDateTime.now(); + this.modifiedDate = ZonedDateTime.now(); + } - @PreUpdate - protected void onUpdate() { - this.modifiedDate = ZonedDateTime.now(); - } + @PreUpdate + protected void onUpdate() { + this.modifiedDate = ZonedDateTime.now(); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/QueryDslConfig.java b/src/main/java/com/kamco/cd/kamcoback/postgres/QueryDslConfig.java index 6212f6e3..97f24b0d 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/QueryDslConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/QueryDslConfig.java @@ -10,10 +10,10 @@ import org.springframework.context.annotation.Configuration; @Configuration public class QueryDslConfig { - private final EntityManager entityManager; + private final EntityManager entityManager; - @Bean - public JPAQueryFactory jpaQueryFactory() { - return new JPAQueryFactory(entityManager); - } + @Bean + public JPAQueryFactory jpaQueryFactory() { + return new JPAQueryFactory(entityManager); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/AnimalCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/AnimalCoreService.java index bf72b375..a7be2a03 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/AnimalCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/AnimalCoreService.java @@ -16,67 +16,59 @@ import org.springframework.transaction.annotation.Transactional; @RequiredArgsConstructor @Transactional(readOnly = true) public class AnimalCoreService - implements BaseCoreService { + implements BaseCoreService { - private final AnimalRepository animalRepository; - private final ZooRepository zooRepository; + private final AnimalRepository animalRepository; + private final ZooRepository zooRepository; - @Transactional(readOnly = true) - public AnimalDto.Basic getDataByUuid(String uuid) { - AnimalEntity getZoo = - animalRepository - .getAnimalByUuid(uuid) - .orElseThrow( - () -> - new EntityNotFoundException( - "Zoo not found with uuid: " + uuid)); - return getZoo.toDto(); + @Transactional(readOnly = true) + public AnimalDto.Basic getDataByUuid(String uuid) { + AnimalEntity getZoo = + animalRepository + .getAnimalByUuid(uuid) + .orElseThrow(() -> new EntityNotFoundException("Zoo not found with uuid: " + uuid)); + return getZoo.toDto(); + } + + // AddReq를 받는 추가 메서드 + @Transactional + public AnimalDto.Basic create(AnimalDto.AddReq req) { + ZooEntity zoo = null; + if (req.getZooId() != null) { + zoo = + zooRepository + .getZooByUid(req.getZooId()) + .orElseThrow( + () -> new EntityNotFoundException(" not found with id: " + req.getZooId())); } + AnimalEntity entity = new AnimalEntity(req.getCategory(), req.getSpecies(), req.getName(), zoo); + AnimalEntity saved = animalRepository.save(entity); + return saved.toDto(); + } - // AddReq를 받는 추가 메서드 - @Transactional - public AnimalDto.Basic create(AnimalDto.AddReq req) { - ZooEntity zoo = null; - if (req.getZooId() != null) { - zoo = - zooRepository - .getZooByUid(req.getZooId()) - .orElseThrow( - () -> - new EntityNotFoundException( - "Zoo not found with id: " + req.getZooId())); - } - AnimalEntity entity = - new AnimalEntity(req.getCategory(), req.getSpecies(), req.getName(), zoo); - AnimalEntity saved = animalRepository.save(entity); - return saved.toDto(); - } + @Override + @Transactional + public void remove(Long id) { + AnimalEntity getAnimal = + animalRepository + .getAnimalByUid(id) + .orElseThrow(() -> new EntityNotFoundException("getAnimal not found with id: " + id)); + getAnimal.deleted(); + } - @Override - @Transactional - public void remove(Long id) { - AnimalEntity getZoo = - animalRepository - .getAnimalByUid(id) - .orElseThrow( - () -> new EntityNotFoundException("Zoo not found with id: " + id)); - getZoo.deleted(); - } + @Override + public AnimalDto.Basic getOneById(Long id) { + AnimalEntity getAnimal = + animalRepository + .getAnimalByUid(id) + .orElseThrow(() -> new EntityNotFoundException("Zoo not found with id: " + id)); + return getAnimal.toDto(); + } - @Override - public AnimalDto.Basic getOneById(Long id) { - AnimalEntity getZoo = - animalRepository - .getAnimalByUid(id) - .orElseThrow( - () -> new EntityNotFoundException("Zoo not found with id: " + id)); - return getZoo.toDto(); - } + @Override + public Page search(AnimalDto.SearchReq searchReq) { - @Override - public Page search(AnimalDto.SearchReq searchReq) { - - Page zooEntities = animalRepository.listAnimal(searchReq); - return zooEntities.map(AnimalEntity::toDto); - } + Page animalEntities = animalRepository.listAnimal(searchReq); + return animalEntities.map(AnimalEntity::toDto); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/ZooCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/ZooCoreService.java index 2d96d2f8..dd732435 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/ZooCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/ZooCoreService.java @@ -15,66 +15,61 @@ import org.springframework.transaction.annotation.Transactional; @Transactional(readOnly = true) public class ZooCoreService implements BaseCoreService { - private final ZooRepository zooRepository; + private final ZooRepository zooRepository; - @Transactional(readOnly = true) - public ZooDto.Detail getDataByUuid(String uuid) { - ZooEntity zoo = - zooRepository - .getZooByUuid(uuid) - .orElseThrow( - () -> - new EntityNotFoundException( - "Zoo not found with uuid: " + uuid)); - return toDetailDto(zoo); - } + @Transactional(readOnly = true) + public ZooDto.Detail getDataByUuid(String uuid) { + ZooEntity zoo = + zooRepository + .getZooByUuid(uuid) + .orElseThrow(() -> new EntityNotFoundException("Zoo not found with uuid: " + uuid)); + return toDetailDto(zoo); + } - // AddReq를 받는 추가 메서드 - @Transactional - public ZooDto.Detail create(ZooDto.AddReq req) { - ZooEntity entity = new ZooEntity(req.getName(), req.getLocation(), req.getDescription()); - ZooEntity saved = zooRepository.save(entity); - return toDetailDto(saved); - } + // AddReq를 받는 추가 메서드 + @Transactional + public ZooDto.Detail create(ZooDto.AddReq req) { + ZooEntity entity = new ZooEntity(req.getName(), req.getLocation(), req.getDescription()); + ZooEntity saved = zooRepository.save(entity); + return toDetailDto(saved); + } - @Override - @Transactional - public void remove(Long id) { - ZooEntity zoo = - zooRepository - .getZooByUid(id) - .orElseThrow( - () -> new EntityNotFoundException("Zoo not found with id: " + id)); - zoo.deleted(); - } + @Override + @Transactional + public void remove(Long id) { + ZooEntity zoo = + zooRepository + .getZooByUid(id) + .orElseThrow(() -> new EntityNotFoundException("Zoo not found with id: " + id)); + zoo.deleted(); + } - @Override - public ZooDto.Detail getOneById(Long id) { - ZooEntity zoo = - zooRepository - .getZooByUid(id) - .orElseThrow( - () -> new EntityNotFoundException("Zoo not found with id: " + id)); - return toDetailDto(zoo); - } + @Override + public ZooDto.Detail getOneById(Long id) { + ZooEntity zoo = + zooRepository + .getZooByUid(id) + .orElseThrow(() -> new EntityNotFoundException("Zoo not found with id: " + id)); + return toDetailDto(zoo); + } - @Override - public Page search(ZooDto.SearchReq searchReq) { - Page zooEntities = zooRepository.listZoo(searchReq); - return zooEntities.map(this::toDetailDto); - } + @Override + public Page search(ZooDto.SearchReq searchReq) { + Page zooEntities = zooRepository.listZoo(searchReq); + return zooEntities.map(this::toDetailDto); + } - // Entity -> Detail DTO 변환 (동물 개수 포함) - private ZooDto.Detail toDetailDto(ZooEntity zoo) { - Long activeAnimalCount = zooRepository.countActiveAnimals(zoo.getUid()); - return new ZooDto.Detail( - zoo.getUid(), - zoo.getUuid().toString(), - zoo.getName(), - zoo.getLocation(), - zoo.getDescription(), - zoo.getCreatedDate(), - zoo.getModifiedDate(), - activeAnimalCount); - } + // Entity -> Detail DTO 변환 (동물 개수 포함) + private ZooDto.Detail toDetailDto(ZooEntity zoo) { + Long activeAnimalCount = zooRepository.countActiveAnimals(zoo.getUid()); + return new ZooDto.Detail( + zoo.getUid(), + zoo.getUuid().toString(), + zoo.getName(), + zoo.getLocation(), + zoo.getDescription(), + zoo.getCreatedDate(), + zoo.getModifiedDate(), + activeAnimalCount); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/AnimalEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/AnimalEntity.java index 8844d135..c6d78000 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/AnimalEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/AnimalEntity.java @@ -28,48 +28,48 @@ import lombok.NoArgsConstructor; @Table(name = "tb_animal") public class AnimalEntity extends CommonDateEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long uid; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long uid; - @Column(unique = true) - private UUID uuid; + @Column(unique = true) + private UUID uuid; - @Enumerated(EnumType.STRING) - private Category category; + @Enumerated(EnumType.STRING) + private Category category; - @Enumerated(EnumType.STRING) - private Species species; + @Enumerated(EnumType.STRING) + private Species species; - private String name; - private Boolean isDeleted; + private String name; + private Boolean isDeleted; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "zoo_id") - private ZooEntity zoo; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "zoo_id") + private ZooEntity zoo; - // Construct - public AnimalEntity(Category category, Species species, String name, ZooEntity zoo) { - this.uuid = UUID.randomUUID(); - this.category = category; - this.species = species; - this.name = name; - this.isDeleted = false; - this.zoo = zoo; - } + // Construct + public AnimalEntity(Category category, Species species, String name, ZooEntity zoo) { + this.uuid = UUID.randomUUID(); + this.category = category; + this.species = species; + this.name = name; + this.isDeleted = false; + this.zoo = zoo; + } - public AnimalDto.Basic toDto() { - return new AnimalDto.Basic( - this.uid, - this.uuid.toString(), - this.name, - this.category, - this.species, - super.getCreatedDate(), - super.getModifiedDate()); - } + public AnimalDto.Basic toDto() { + return new AnimalDto.Basic( + this.uid, + this.uuid.toString(), + this.name, + this.category, + this.species, + super.getCreatedDate(), + super.getModifiedDate()); + } - public void deleted() { - this.isDeleted = true; - } + public void deleted() { + this.isDeleted = true; + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/ZooEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/ZooEntity.java index b135b67b..9d7f18b4 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/ZooEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/ZooEntity.java @@ -23,44 +23,44 @@ import lombok.NoArgsConstructor; @Table(name = "tb_zoo") public class ZooEntity extends CommonDateEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long uid; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long uid; - @Column(unique = true, nullable = false) - private UUID uuid; + @Column(unique = true, nullable = false) + private UUID uuid; - @Column(nullable = false, length = 200) - private String name; + @Column(nullable = false, length = 200) + private String name; - @Column(length = 300) - private String location; + @Column(length = 300) + private String location; - @Column(columnDefinition = "TEXT") - private String description; + @Column(columnDefinition = "TEXT") + private String description; - @Column(nullable = false) - private Boolean isDeleted; + @Column(nullable = false) + private Boolean isDeleted; - @OneToMany(mappedBy = "zoo", fetch = FetchType.LAZY, cascade = CascadeType.ALL) - private List animals = new ArrayList<>(); + @OneToMany(mappedBy = "zoo", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + private List animals = new ArrayList<>(); - // Constructor - public ZooEntity(String name, String location, String description) { - this.uuid = UUID.randomUUID(); - this.name = name; - this.location = location; - this.description = description; - this.isDeleted = false; - } + // Constructor + public ZooEntity(String name, String location, String description) { + this.uuid = UUID.randomUUID(); + this.name = name; + this.location = location; + this.description = description; + this.isDeleted = false; + } - // 논리 삭제 - public void deleted() { - this.isDeleted = true; - } + // 논리 삭제 + public void deleted() { + this.isDeleted = true; + } - // 현재 활성 동물 개수 조회 (삭제되지 않은 동물만) - public long getActiveAnimalCount() { - return animals.stream().filter(animal -> !animal.getIsDeleted()).count(); - } + // 현재 활성 동물 개수 조회 (삭제되지 않은 동물만) + public long getActiveAnimalCount() { + return animals.stream().filter(animal -> !animal.getIsDeleted()).count(); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepository.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepository.java index cf78ffdb..c549fecf 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepository.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepository.java @@ -4,4 +4,4 @@ import com.kamco.cd.kamcoback.postgres.entity.AnimalEntity; import org.springframework.data.jpa.repository.JpaRepository; public interface AnimalRepository - extends JpaRepository, AnimalRepositoryCustom {} + extends JpaRepository, AnimalRepositoryCustom {} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepositoryCustom.java index 79a39a27..7e95efc0 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepositoryCustom.java @@ -7,9 +7,9 @@ import org.springframework.data.domain.Page; public interface AnimalRepositoryCustom { - Optional getAnimalByUid(Long uid); + Optional getAnimalByUid(Long uid); - Optional getAnimalByUuid(String uuid); + Optional getAnimalByUuid(String uuid); - Page listAnimal(AnimalDto.SearchReq req); + Page listAnimal(AnimalDto.SearchReq req); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepositoryImpl.java index d54e26fd..5e9b4826 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/AnimalRepositoryImpl.java @@ -16,84 +16,81 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; public class AnimalRepositoryImpl extends QuerydslRepositorySupport - implements AnimalRepositoryCustom { + implements AnimalRepositoryCustom { - private final JPAQueryFactory queryFactory; + private final JPAQueryFactory queryFactory; - public AnimalRepositoryImpl(JPAQueryFactory queryFactory) { - super(AnimalEntity.class); - this.queryFactory = queryFactory; + public AnimalRepositoryImpl(JPAQueryFactory queryFactory) { + super(AnimalEntity.class); + this.queryFactory = queryFactory; + } + + public Optional getAnimalByUid(Long uid) { + QAnimalEntity animal = QAnimalEntity.animalEntity; + + return Optional.ofNullable( + queryFactory.selectFrom(animal).where(animal.uid.eq(uid)).fetchFirst()); + } + + public Optional getAnimalByUuid(String uuid) { + QAnimalEntity animal = QAnimalEntity.animalEntity; + + return Optional.ofNullable( + queryFactory.selectFrom(animal).where(animal.uuid.eq(UUID.fromString(uuid))).fetchFirst()); + } + + @Override + public Page listAnimal(AnimalDto.SearchReq req) { + QAnimalEntity animal = QAnimalEntity.animalEntity; + + Pageable pageable = req.toPageable(); + + List content = + queryFactory + .selectFrom(animal) + .where( + animal.isDeleted.eq(false), + eqCategory(animal, req.getCategory()), + eqSpecies(animal, req.getSpecies()), + likeName(animal, req.getName())) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(animal.createdDate.desc()) + .fetch(); + + // count 쿼리 + Long total = + queryFactory + .select(animal.count()) + .from(animal) + .where( + animal.isDeleted.eq(false), + eqCategory(animal, req.getCategory()), + eqSpecies(animal, req.getSpecies()), + likeName(animal, req.getName())) + .fetchOne(); + + return new PageImpl<>(content, pageable, total); + } + + private BooleanExpression likeName(QAnimalEntity animal, String nameStr) { + if (nameStr == null || nameStr.isEmpty()) { + return null; } + return animal.name.containsIgnoreCase(nameStr.trim()); + } - public Optional getAnimalByUid(Long uid) { - QAnimalEntity animal = QAnimalEntity.animalEntity; - - return Optional.ofNullable( - queryFactory.selectFrom(animal).where(animal.uid.eq(uid)).fetchFirst()); + private BooleanExpression eqCategory(QAnimalEntity animal, Category category) { + if (category == null) { + return null; } + return animal.category.eq(category); + } - public Optional getAnimalByUuid(String uuid) { - QAnimalEntity animal = QAnimalEntity.animalEntity; - - return Optional.ofNullable( - queryFactory - .selectFrom(animal) - .where(animal.uuid.eq(UUID.fromString(uuid))) - .fetchFirst()); - } - - @Override - public Page listAnimal(AnimalDto.SearchReq req) { - QAnimalEntity animal = QAnimalEntity.animalEntity; - - Pageable pageable = req.toPageable(); - - List content = - queryFactory - .selectFrom(animal) - .where( - animal.isDeleted.eq(false), - eqCategory(animal, req.getCategory()), - eqSpecies(animal, req.getSpecies()), - likeName(animal, req.getName())) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .orderBy(animal.createdDate.desc()) - .fetch(); - - // count 쿼리 - Long total = - queryFactory - .select(animal.count()) - .from(animal) - .where( - animal.isDeleted.eq(false), - eqCategory(animal, req.getCategory()), - eqSpecies(animal, req.getSpecies()), - likeName(animal, req.getName())) - .fetchOne(); - - return new PageImpl<>(content, pageable, total); - } - - private BooleanExpression likeName(QAnimalEntity animal, String nameStr) { - if (nameStr == null || nameStr.isEmpty()) { - return null; - } - return animal.name.containsIgnoreCase(nameStr.trim()); - } - - private BooleanExpression eqCategory(QAnimalEntity animal, Category category) { - if (category == null) { - return null; - } - return animal.category.eq(category); - } - - private BooleanExpression eqSpecies(QAnimalEntity animal, Species species) { - if (species == null) { - return null; - } - return animal.species.eq(species); + private BooleanExpression eqSpecies(QAnimalEntity animal, Species species) { + if (species == null) { + return null; } + return animal.species.eq(species); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/ZooRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/ZooRepositoryCustom.java index caf583e6..e053b4f0 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/ZooRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/ZooRepositoryCustom.java @@ -7,11 +7,11 @@ import org.springframework.data.domain.Page; public interface ZooRepositoryCustom { - Page listZoo(ZooDto.SearchReq searchReq); + Page listZoo(ZooDto.SearchReq searchReq); - Optional getZooByUuid(String uuid); + Optional getZooByUuid(String uuid); - Optional getZooByUid(Long uid); + Optional getZooByUid(Long uid); - Long countActiveAnimals(Long zooId); + Long countActiveAnimals(Long zooId); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/ZooRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/ZooRepositoryImpl.java index 62bdf94f..7d6ffa63 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/ZooRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/ZooRepositoryImpl.java @@ -20,68 +20,66 @@ import org.springframework.stereotype.Repository; @RequiredArgsConstructor public class ZooRepositoryImpl implements ZooRepositoryCustom { - private final JPAQueryFactory queryFactory; - private final QZooEntity qZoo = QZooEntity.zooEntity; - private final QAnimalEntity qAnimal = QAnimalEntity.animalEntity; + private final JPAQueryFactory queryFactory; + private final QZooEntity qZoo = QZooEntity.zooEntity; + private final QAnimalEntity qAnimal = QAnimalEntity.animalEntity; - @Override - public Page listZoo(ZooDto.SearchReq searchReq) { - Pageable pageable = searchReq.toPageable(); + @Override + public Page listZoo(ZooDto.SearchReq searchReq) { + Pageable pageable = searchReq.toPageable(); - JPAQuery query = - queryFactory - .selectFrom(qZoo) - .where( - qZoo.isDeleted.eq(false), - nameContains(searchReq.getName()), - locationContains(searchReq.getLocation())); + JPAQuery query = + queryFactory + .selectFrom(qZoo) + .where( + qZoo.isDeleted.eq(false), + nameContains(searchReq.getName()), + locationContains(searchReq.getLocation())); - long total = query.fetchCount(); + long total = query.fetchCount(); - List content = - query.offset(pageable.getOffset()) - .limit(pageable.getPageSize()) - .orderBy(qZoo.createdDate.desc()) - .fetch(); + List content = + query + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(qZoo.createdDate.desc()) + .fetch(); - return new PageImpl<>(content, pageable, total); - } + return new PageImpl<>(content, pageable, total); + } - @Override - public Optional getZooByUuid(String uuid) { - return Optional.ofNullable( - queryFactory - .selectFrom(qZoo) - .where(qZoo.uuid.eq(UUID.fromString(uuid)), qZoo.isDeleted.eq(false)) - .fetchOne()); - } + @Override + public Optional getZooByUuid(String uuid) { + return Optional.ofNullable( + queryFactory + .selectFrom(qZoo) + .where(qZoo.uuid.eq(UUID.fromString(uuid)), qZoo.isDeleted.eq(false)) + .fetchOne()); + } - @Override - public Optional getZooByUid(Long uid) { - return Optional.ofNullable( - queryFactory - .selectFrom(qZoo) - .where(qZoo.uid.eq(uid), qZoo.isDeleted.eq(false)) - .fetchOne()); - } + @Override + public Optional getZooByUid(Long uid) { + return Optional.ofNullable( + queryFactory.selectFrom(qZoo).where(qZoo.uid.eq(uid), qZoo.isDeleted.eq(false)).fetchOne()); + } - @Override - public Long countActiveAnimals(Long zooId) { - Long count = - queryFactory - .select(qAnimal.count()) - .from(qAnimal) - .where(qAnimal.zoo.uid.eq(zooId), qAnimal.isDeleted.eq(false)) - .fetchOne(); + @Override + public Long countActiveAnimals(Long zooId) { + Long count = + queryFactory + .select(qAnimal.count()) + .from(qAnimal) + .where(qAnimal.zoo.uid.eq(zooId), qAnimal.isDeleted.eq(false)) + .fetchOne(); - return count != null ? count : 0L; - } + return count != null ? count : 0L; + } - private BooleanExpression nameContains(String name) { - return name != null && !name.isEmpty() ? qZoo.name.contains(name) : null; - } + private BooleanExpression nameContains(String name) { + return name != null && !name.isEmpty() ? qZoo.name.contains(name) : null; + } - private BooleanExpression locationContains(String location) { - return location != null && !location.isEmpty() ? qZoo.location.contains(location) : null; - } + private BooleanExpression locationContains(String location) { + return location != null && !location.isEmpty() ? qZoo.location.contains(location) : null; + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/zoo/AnimalApiController.java b/src/main/java/com/kamco/cd/kamcoback/zoo/AnimalApiController.java index 87a0c2bc..226de0d6 100644 --- a/src/main/java/com/kamco/cd/kamcoback/zoo/AnimalApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/zoo/AnimalApiController.java @@ -15,68 +15,68 @@ import org.springframework.web.bind.annotation.*; @RequestMapping({"/api/animals", "/v1/api/animals"}) public class AnimalApiController { - private final AnimalService animalService; + private final AnimalService animalService; - /** - * 동물 생성 - * - * @param req 동물 생성 요청 - * @return 생성된 동물 정보 - */ - @PostMapping - public ResponseEntity createAnimal(@RequestBody AnimalDto.AddReq req) { - AnimalDto.Basic created = animalService.createAnimal(req); - return ResponseEntity.status(HttpStatus.CREATED).body(created); - } + /** + * 동물 생성 + * + * @param req 동물 생성 요청 + * @return 생성된 동물 정보 + */ + @PostMapping + public ResponseEntity createAnimal(@RequestBody AnimalDto.AddReq req) { + AnimalDto.Basic created = animalService.createAnimal(req); + return ResponseEntity.status(HttpStatus.CREATED).body(created); + } - /** - * UUID로 동물 조회 - * - * @param uuid 동물 UUID - * @return 동물 정보 - */ - @GetMapping("/{uuid}") - public ResponseEntity getAnimal(@PathVariable String uuid) { - Long id = animalService.getAnimalByUuid(uuid); - AnimalDto.Basic animal = animalService.getAnimal(id); - return ResponseEntity.ok(animal); - } + /** + * UUID로 동물 조회 + * + * @param uuid 동물 UUID + * @return 동물 정보 + */ + @GetMapping("/{uuid}") + public ResponseEntity getAnimal(@PathVariable String uuid) { + Long id = animalService.getAnimalByUuid(uuid); + AnimalDto.Basic animal = animalService.getAnimal(id); + return ResponseEntity.ok(animal); + } - /** - * UUID로 동물 삭제 (논리 삭제) - * - * @param uuid 동물 UUID - * @return 삭제 성공 메시지 - */ - @DeleteMapping("/{uuid}") - public ResponseEntity deleteAnimal(@PathVariable String uuid) { - Long id = animalService.getAnimalByUuid(uuid); - animalService.deleteZoo(id); - return ResponseEntity.noContent().build(); - } + /** + * UUID로 동물 삭제 (논리 삭제) + * + * @param uuid 동물 UUID + * @return 삭제 성공 메시지 + */ + @DeleteMapping("/{uuid}") + public ResponseEntity deleteAnimal(@PathVariable String uuid) { + Long id = animalService.getAnimalByUuid(uuid); + animalService.deleteZoo(id); + return ResponseEntity.noContent().build(); + } - /** - * 동물 검색 (페이징) - * - * @param name 동물 이름 (선택) - * @param category 서식지 타입 (선택) - * @param species 동물종 (선택) 개, 고양이등. - * @param page 페이지 번호 (기본값: 0) - * @param size 페이지 크기 (기본값: 20) - * @param sort 정렬 조건 (예: "name,asc") - * @return 페이징 처리된 동물 목록 - */ - @GetMapping - public ResponseEntity> searchAnimals( - @RequestParam(required = false) String name, - @RequestParam(required = false) Category category, - @RequestParam(required = false) Species species, - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "20") int size, - @RequestParam(required = false) String sort) { - AnimalDto.SearchReq searchReq = - new AnimalDto.SearchReq(name, category, species, page, size, sort); - Page animals = animalService.search(searchReq); - return ResponseEntity.ok(animals); - } + /** + * 동물 검색 (페이징) + * + * @param name 동물 이름 (선택) + * @param category 서식지 타입 (선택) + * @param species 동물종 (선택) 개, 고양이등. + * @param page 페이지 번호 (기본값: 0) + * @param size 페이지 크기 (기본값: 20) + * @param sort 정렬 조건 (예: "name,asc") + * @return 페이징 처리된 동물 목록 + */ + @GetMapping + public ResponseEntity> searchAnimals( + @RequestParam(required = false) String name, + @RequestParam(required = false) Category category, + @RequestParam(required = false) Species species, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "20") int size, + @RequestParam(required = false) String sort) { + AnimalDto.SearchReq searchReq = + new AnimalDto.SearchReq(name, category, species, page, size, sort); + Page animals = animalService.search(searchReq); + return ResponseEntity.ok(animals); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/zoo/ZooApiController.java b/src/main/java/com/kamco/cd/kamcoback/zoo/ZooApiController.java index a66ad94c..c1e24dac 100644 --- a/src/main/java/com/kamco/cd/kamcoback/zoo/ZooApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/zoo/ZooApiController.java @@ -56,20 +56,20 @@ public class ZooApiController { /** * 동물원 검색 (페이징) * - * @param name 동물원 이름 (선택) + * @param name 동물원 이름 (선택) * @param location 위치 (선택) - * @param page 페이지 번호 (기본값: 0) - * @param size 페이지 크기 (기본값: 20) - * @param sort 정렬 조건 (예: "name,asc") + * @param page 페이지 번호 (기본값: 0) + * @param size 페이지 크기 (기본값: 20) + * @param sort 정렬 조건 (예: "name,asc") * @return 페이징 처리된 동물원 목록 (각 동물원의 현재 동물 개수 포함) */ @GetMapping public ResponseEntity> searchZoos( - @RequestParam(required = false) String name, - @RequestParam(required = false) String location, - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "20") int size, - @RequestParam(required = false) String sort) { + @RequestParam(required = false) String name, + @RequestParam(required = false) String location, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "20") int size, + @RequestParam(required = false) String sort) { ZooDto.SearchReq searchReq = new ZooDto.SearchReq(name, location, page, size, sort); Page zoos = zooService.search(searchReq); return ResponseEntity.ok(zoos); diff --git a/src/main/java/com/kamco/cd/kamcoback/zoo/dto/AnimalDto.java b/src/main/java/com/kamco/cd/kamcoback/zoo/dto/AnimalDto.java index 856d256d..3fa2b9b6 100644 --- a/src/main/java/com/kamco/cd/kamcoback/zoo/dto/AnimalDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/zoo/dto/AnimalDto.java @@ -29,33 +29,32 @@ public class AnimalDto { @Getter public static class Basic { - @JsonIgnore - private Long id; + @JsonIgnore private Long id; private String uuid; private Category category; private Species species; private String name; @JsonFormat( - shape = JsonFormat.Shape.STRING, - pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", - timezone = "Asia/Seoul") + shape = JsonFormat.Shape.STRING, + pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", + timezone = "Asia/Seoul") private ZonedDateTime createdDate; @JsonFormat( - shape = JsonFormat.Shape.STRING, - pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", - timezone = "Asia/Seoul") + shape = JsonFormat.Shape.STRING, + pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", + timezone = "Asia/Seoul") private ZonedDateTime modifiedDate; public Basic( - Long id, - String uuid, - String name, - Category category, - Species species, - ZonedDateTime createdDate, - ZonedDateTime modifiedDate) { + Long id, + String uuid, + String name, + Category category, + Species species, + ZonedDateTime createdDate, + ZonedDateTime modifiedDate) { this.id = id; this.uuid = uuid; this.name = name; @@ -70,16 +69,16 @@ public class AnimalDto { @AllArgsConstructor public enum Category implements EnumType { // @formatter:off - MAMMALS("100", "포유류"), // 땅에 사는 동물 - BIRDS("200", "조류"), // 하늘을 나는 동물 - FISH("300", "어류"), - AMPHIBIANS("400", "양서류"), - REPTILES("500", "파충류"), - INSECTS("500", "곤충"), - INVERTEBRATES("500", "무척추동물"), - ; - // @formatter:on - private final String id; + MAMMALS("100", "포유류"), // 땅에 사는 동물 + BIRDS("200", "조류"), // 하늘을 나는 동물 + FISH("300", "어류"), + AMPHIBIANS("400", "양서류"), + REPTILES("500", "파충류"), + INSECTS("500", "곤충"), + INVERTEBRATES("500", "무척추동물"), + ; + // @formatter:on + private final String id; private final String text; } @@ -87,15 +86,15 @@ public class AnimalDto { @AllArgsConstructor public enum Species implements EnumType { // @formatter:off - DOG("101", "개"), - CAT("102", "강아지"), - DOVE("201", "비둘기"), - EAGLE("202", "독수리"), - SALMON("301", "연어"), - TUNA("302", "참치"), - ; - // @formatter:on - private final String id; + DOG("101", "개"), + CAT("102", "강아지"), + DOVE("201", "비둘기"), + EAGLE("202", "독수리"), + SALMON("301", "연어"), + TUNA("302", "참치"), + ; + // @formatter:on + private final String id; private final String text; } @@ -120,9 +119,7 @@ public class AnimalDto { String[] sortParams = sort.split(","); String property = sortParams[0]; Sort.Direction direction = - sortParams.length > 1 - ? Sort.Direction.fromString(sortParams[1]) - : Sort.Direction.ASC; + sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC; return PageRequest.of(page, size, Sort.by(direction, property)); } return PageRequest.of(page, size); diff --git a/src/main/java/com/kamco/cd/kamcoback/zoo/dto/ZooDto.java b/src/main/java/com/kamco/cd/kamcoback/zoo/dto/ZooDto.java index 805419db..ede88299 100644 --- a/src/main/java/com/kamco/cd/kamcoback/zoo/dto/ZooDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/zoo/dto/ZooDto.java @@ -27,33 +27,32 @@ public class ZooDto { @Getter public static class Basic { - @JsonIgnore - private Long id; + @JsonIgnore private Long id; private String uuid; private String name; private String location; private String description; @JsonFormat( - shape = JsonFormat.Shape.STRING, - pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", - timezone = "Asia/Seoul") + shape = JsonFormat.Shape.STRING, + pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", + timezone = "Asia/Seoul") private ZonedDateTime createdDate; @JsonFormat( - shape = JsonFormat.Shape.STRING, - pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", - timezone = "Asia/Seoul") + shape = JsonFormat.Shape.STRING, + pattern = "yyyy-MM-dd'T'HH:mm:ssXXX", + timezone = "Asia/Seoul") private ZonedDateTime modifiedDate; public Basic( - Long id, - String uuid, - String name, - String location, - String description, - ZonedDateTime createdDate, - ZonedDateTime modifiedDate) { + Long id, + String uuid, + String name, + String location, + String description, + ZonedDateTime createdDate, + ZonedDateTime modifiedDate) { this.id = id; this.uuid = uuid; this.name = name; @@ -70,14 +69,14 @@ public class ZooDto { private Long activeAnimalCount; public Detail( - Long id, - String uuid, - String name, - String location, - String description, - ZonedDateTime createdDate, - ZonedDateTime modifiedDate, - Long activeAnimalCount) { + Long id, + String uuid, + String name, + String location, + String description, + ZonedDateTime createdDate, + ZonedDateTime modifiedDate, + Long activeAnimalCount) { super(id, uuid, name, location, description, createdDate, modifiedDate); this.activeAnimalCount = activeAnimalCount; } @@ -103,9 +102,7 @@ public class ZooDto { String[] sortParams = sort.split(","); String property = sortParams[0]; Sort.Direction direction = - sortParams.length > 1 - ? Sort.Direction.fromString(sortParams[1]) - : Sort.Direction.ASC; + sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC; return PageRequest.of(page, size, Sort.by(direction, property)); } return PageRequest.of(page, size); diff --git a/src/main/java/com/kamco/cd/kamcoback/zoo/service/ZooService.java b/src/main/java/com/kamco/cd/kamcoback/zoo/service/ZooService.java index cf773abf..b3f1ba94 100644 --- a/src/main/java/com/kamco/cd/kamcoback/zoo/service/ZooService.java +++ b/src/main/java/com/kamco/cd/kamcoback/zoo/service/ZooService.java @@ -11,51 +11,52 @@ import org.springframework.transaction.annotation.Transactional; @Service @Transactional(readOnly = true) public class ZooService { - private final ZooCoreService zooCoreService; - // 동물원의 UUID로 id조회 - public Long getZooByUuid(String uuid) { - return zooCoreService.getDataByUuid(uuid).getId(); - } + private final ZooCoreService zooCoreService; - /** - * 동물원 생성 - * - * @param req 동물원 생성 요청 - * @return 생성된 동물원 정보 (동물 개수 포함) - */ - @Transactional - public ZooDto.Detail createZoo(ZooDto.AddReq req) { - return zooCoreService.create(req); - } + // 동물원의 UUID로 id조회 + public Long getZooByUuid(String uuid) { + return zooCoreService.getDataByUuid(uuid).getId(); + } - /** - * 동물원 삭제 (논리 삭제) - * - * @param id 동물원 ID - */ - @Transactional - public void deleteZoo(Long id) { - zooCoreService.remove(id); - } + /** + * 동물원 생성 + * + * @param req 동물원 생성 요청 + * @return 생성된 동물원 정보 (동물 개수 포함) + */ + @Transactional + public ZooDto.Detail createZoo(ZooDto.AddReq req) { + return zooCoreService.create(req); + } - /** - * 동물원 단건 조회 - * - * @param id 동물원 ID - * @return 동물원 정보 (동물 개수 포함) - */ - public ZooDto.Detail getZoo(Long id) { - return zooCoreService.getOneById(id); - } + /** + * 동물원 삭제 (논리 삭제) + * + * @param id 동물원 ID + */ + @Transactional + public void deleteZoo(Long id) { + zooCoreService.remove(id); + } - /** - * 동물원 검색 (페이징) - * - * @param searchReq 검색 조건 - * @return 페이징 처리된 동물원 목록 (각 동물원의 동물 개수 포함) - */ - public Page search(ZooDto.SearchReq searchReq) { - return zooCoreService.search(searchReq); - } + /** + * 동물원 단건 조회 + * + * @param id 동물원 ID + * @return 동물원 정보 (동물 개수 포함) + */ + public ZooDto.Detail getZoo(Long id) { + return zooCoreService.getOneById(id); + } + + /** + * 동물원 검색 (페이징) + * + * @param searchReq 검색 조건 + * @return 페이징 처리된 동물원 목록 (각 동물원의 동물 개수 포함) + */ + public Page search(ZooDto.SearchReq searchReq) { + return zooCoreService.search(searchReq); + } } diff --git a/src/test/java/com/kamco/cd/kamcoback/KamcoBackApplicationTests.java b/src/test/java/com/kamco/cd/kamcoback/KamcoBackApplicationTests.java index c3272fb3..258574d6 100644 --- a/src/test/java/com/kamco/cd/kamcoback/KamcoBackApplicationTests.java +++ b/src/test/java/com/kamco/cd/kamcoback/KamcoBackApplicationTests.java @@ -6,6 +6,6 @@ import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class KamcoBackApplicationTests { - @Test - void contextLoads() {} + @Test + void contextLoads() {} }