diff --git a/src/main/java/com/example/urlshortener/domain/url/controller/Week4Controller.java b/src/main/java/com/example/urlshortener/domain/url/controller/Week4Controller.java new file mode 100644 index 0000000..db74bb1 --- /dev/null +++ b/src/main/java/com/example/urlshortener/domain/url/controller/Week4Controller.java @@ -0,0 +1,51 @@ +package com.example.urlshortener.domain.url.controller; + +import com.example.urlshortener.common.dto.Response; +import com.example.urlshortener.domain.url.dto.ShortenedUrlDto; +import com.example.urlshortener.domain.url.service.UrlService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotBlank; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/short-links/list") +@Tag(name = "๐Ÿƒ 4์ฃผ์ฐจ ๊ณผ์ œ", description = "4์ฃผ์ฐจ ๊ณผ์ œ์ž…๋‹ˆ๋‹ค.") +public class Week4Controller { + + private final UrlService urlService; + + @Operation( + summary = "Data JPA๋กœ URL ์กฐํšŒํ•˜๊ธฐ", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR") + } + ) + @GetMapping("/jpa") + public Response> getShortUrlsWithJpa(@NotBlank @RequestParam("inquiry") String inquiry) { + List shortenedUrls = urlService.getShortUrlsWithJpa(inquiry); + return Response.data(shortenedUrls); + } + + @Operation( + summary = "QueryDsl๋กœ URL ์กฐํšŒํ•˜๊ธฐ", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "500", description = "INTERNAL_SERVER_ERROR") + } + ) + @GetMapping("/query-dsl") + public Response> getShortUrl(@NotBlank @RequestParam("inquiry") String inquiry) { + List shortenedUrls = urlService.getShortUrlsWithQueryDsl(inquiry); + return Response.data(shortenedUrls); + } +} diff --git a/src/main/java/com/example/urlshortener/domain/url/dto/ShortenedUrlDto.java b/src/main/java/com/example/urlshortener/domain/url/dto/ShortenedUrlDto.java index d63a599..d0fbba7 100644 --- a/src/main/java/com/example/urlshortener/domain/url/dto/ShortenedUrlDto.java +++ b/src/main/java/com/example/urlshortener/domain/url/dto/ShortenedUrlDto.java @@ -6,6 +6,8 @@ import lombok.Getter; import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; @Getter @AllArgsConstructor @@ -25,4 +27,10 @@ public static ShortenedUrlDto from(ShortenedUrl shortenedUrl) { .createdAt(shortenedUrl.getCreatedAt()) .build(); } + + public static List from(List shortenedUrls) { + return shortenedUrls.stream() + .map(ShortenedUrlDto::from) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/com/example/urlshortener/domain/url/repository/ShortenedUrlQueryRepository.java b/src/main/java/com/example/urlshortener/domain/url/repository/ShortenedUrlQueryRepository.java new file mode 100644 index 0000000..22e2a1b --- /dev/null +++ b/src/main/java/com/example/urlshortener/domain/url/repository/ShortenedUrlQueryRepository.java @@ -0,0 +1,26 @@ +package com.example.urlshortener.domain.url.repository; + +import com.example.urlshortener.domain.url.dto.ShortenedUrlDto; +import com.example.urlshortener.domain.url.entity.QShortenedUrl; +import com.example.urlshortener.domain.url.entity.ShortenedUrl; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class ShortenedUrlQueryRepository { + private final JPAQueryFactory jpaQueryFactory; + + public List getShortUrlsWithQueryDsl(String inquiry) { + QShortenedUrl shortenedUrl = QShortenedUrl.shortenedUrl; + List shortenedUrls = jpaQueryFactory + .selectFrom(shortenedUrl) + .where(shortenedUrl.originUrl.contains(inquiry)) + .fetch(); + + return ShortenedUrlDto.from(shortenedUrls); + } +} diff --git a/src/main/java/com/example/urlshortener/domain/url/repository/ShortenedUrlRepository.java b/src/main/java/com/example/urlshortener/domain/url/repository/ShortenedUrlRepository.java index 8364d9e..f9d9b0b 100644 --- a/src/main/java/com/example/urlshortener/domain/url/repository/ShortenedUrlRepository.java +++ b/src/main/java/com/example/urlshortener/domain/url/repository/ShortenedUrlRepository.java @@ -11,6 +11,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository @@ -36,4 +37,6 @@ public interface ShortenedUrlRepository extends JpaRepository findShortenedUrlByOriginUrl(String originUrl); + + List findAllByOriginUrlContains(String inquiry); } diff --git a/src/main/java/com/example/urlshortener/domain/url/service/UrlService.java b/src/main/java/com/example/urlshortener/domain/url/service/UrlService.java index 4d60928..14db97b 100644 --- a/src/main/java/com/example/urlshortener/domain/url/service/UrlService.java +++ b/src/main/java/com/example/urlshortener/domain/url/service/UrlService.java @@ -4,17 +4,20 @@ import com.example.urlshortener.domain.url.dto.ShortenedUrlDto; import com.example.urlshortener.domain.url.entity.ShortenedUrl; import com.example.urlshortener.domain.url.exception.UrlNotFoundException; +import com.example.urlshortener.domain.url.repository.ShortenedUrlQueryRepository; import com.example.urlshortener.domain.url.repository.ShortenedUrlRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.time.LocalDateTime; +import java.util.List; @Service @RequiredArgsConstructor public class UrlService { private final ShortenedUrlRepository shortenedUrlRepository; + private final ShortenedUrlQueryRepository shortenedUrlQueryRepository; @Transactional public ShortenedUrlDto createShortUrl(String url) { @@ -45,4 +48,14 @@ public String getOriginUrl(String shortId) { return shortenedUrl.getOriginUrl(); } + + public List getShortUrlsWithJpa(String inquiry) { + List shortenedUrls = shortenedUrlRepository.findAllByOriginUrlContains(inquiry); + + return ShortenedUrlDto.from(shortenedUrls); + } + + public List getShortUrlsWithQueryDsl(String inquiry) { + return shortenedUrlQueryRepository.getShortUrlsWithQueryDsl(inquiry); + } } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 6058902..8941a22 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -17,7 +17,7 @@ spring: jpa: database-platform: org.hibernate.dialect.H2Dialect hibernate: - ddl-auto: create # (none, create, create-drop, update, validate) + ddl-auto: none # (none, create, create-drop, update, validate) properties: hibernate: dialect: org.hibernate.dialect.H2Dialect # Dialect: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ํŠน์ • SQL ๋ฌธ๋ฒ•๊ณผ ๋ฐ์ดํ„ฐ ํƒ€์ž… ๋งคํ•‘์— ๋Œ€ํ•œ ๊ทœ์น™์„ ์ œ๊ณต @@ -25,11 +25,11 @@ spring: show_sql: true # SQL ์ฟผ๋ฆฌ๋ฅผ ์ถœ๋ ฅํ• ์ง€ ์—ฌ๋ถ€ ์„ค์ • # TODO: ๋ฐœํ‘œ ํ›„ ddl-auto: create ๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ(๋ณดํ†ต ddl-auto๋กœ ์‚ฌ์šฉํ•จ) -# sql: -# init: -# mode: always # ddl-auto: none, H2๋Š” ํ•„์š”์—†์Œ(์–ด์ฐจํ”ผ ์‚ฌ๋ผ์ง€๊ธฐ ๋•Œ๋ฌธ) -# schema-locations: classpath:db-init-scripts/schema.sql -# data-locations: classpath:db-init-scripts/data.sql + sql: + init: + mode: always # ddl-auto: none, H2๋Š” ํ•„์š”์—†์Œ(์–ด์ฐจํ”ผ ์‚ฌ๋ผ์ง€๊ธฐ ๋•Œ๋ฌธ) + schema-locations: classpath:db-init-scripts/schema.sql + data-locations: classpath:db-init-scripts/data.sql #logging: # pattern: diff --git a/src/main/resources/db-init-scripts/data.sql b/src/main/resources/db-init-scripts/data.sql index 4ce7521..8e6bbc9 100644 --- a/src/main/resources/db-init-scripts/data.sql +++ b/src/main/resources/db-init-scripts/data.sql @@ -1,6 +1,6 @@ INSERT INTO shortened_url (short_url, origin_url, created_at) VALUES -('http://short.url/abc', 'http://example.com/page1', '2024-04-01 10:00:00'), -('http://short.url/def', 'http://example.com/page2', '2024-04-02 12:00:00'), -('http://short.url/ghi', 'http://example.com/page3', '2024-04-03 14:00:00'), -('http://short.url/jkl', 'http://example.com/page4', '2024-04-04 16:00:00'), -('http://short.url/mno', 'http://example.com/page5', '2024-04-05 18:00:00'); \ No newline at end of file +('abc', 'http://example.com/page1', '2024-04-01 10:00:00'), +('def', 'http://example.com/page2', '2024-04-02 12:00:00'), +('ghi', 'http://example.com/page3', '2024-04-03 14:00:00'), +('jkl', 'http://example.com/page4', '2024-04-04 16:00:00'), +('mno', 'http://example.com/page5', '2024-04-05 18:00:00'); \ No newline at end of file diff --git a/src/test/java/com/example/urlshortener/ch3/Ch3Test3.java b/src/test/java/com/example/urlshortener/ch3/Ch3Test3.java index d9cf5d5..429e8a7 100644 --- a/src/test/java/com/example/urlshortener/ch3/Ch3Test3.java +++ b/src/test/java/com/example/urlshortener/ch3/Ch3Test3.java @@ -19,7 +19,7 @@ class Ch3Test3 { @Test public void givenCreateShortenedUrlWhenLoadTheShortenedUrlThenExpectSameShortenedUrl() { - ShortenedUrl shortenedUrl = new ShortenedUrl("http://short.url/abc", "http://example.com/page1", LocalDateTime.now()); + ShortenedUrl shortenedUrl = new ShortenedUrl("abc", "http://example.com/page1", LocalDateTime.now()); ShortenedUrl savedShortenedUrl = shortenedUrlRepository.save(shortenedUrl); // TODO: ์‹ค์ œ๋กœ๋Š” ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋จ with Transactional @@ -28,7 +28,7 @@ public void givenCreateShortenedUrlWhenLoadTheShortenedUrlThenExpectSameShortene @Test public void givenUpdateShortenedUrlWhenLoadTheShortenedUrlThenExpectUpdatedShortenedUrl() { - ShortenedUrl shortenedUrl = new ShortenedUrl("http://short.url/abc", "http://example.com/page1", LocalDateTime.now()); + ShortenedUrl shortenedUrl = new ShortenedUrl("abc", "http://example.com/page1", LocalDateTime.now()); shortenedUrlRepository.save(shortenedUrl); shortenedUrl.setOriginUrl("http://example.com/page2"); @@ -40,7 +40,7 @@ public void givenUpdateShortenedUrlWhenLoadTheShortenedUrlThenExpectUpdatedShort @Test public void givenDeleteShortenedUrlWhenLoadTheShortenedUrlThenExpectNoShortenedUrl() { - ShortenedUrl shortenedUrl = new ShortenedUrl("http://short.url/abc", "http://example.com/page1", LocalDateTime.now()); + ShortenedUrl shortenedUrl = new ShortenedUrl("abc", "http://example.com/page1", LocalDateTime.now()); ShortenedUrl savedShortenedUrl = shortenedUrlRepository.save(shortenedUrl); assertThat(shortenedUrlRepository.findById(savedShortenedUrl.getId()).get().getId()).isEqualTo(savedShortenedUrl.getId()); diff --git a/src/test/java/com/example/urlshortener/ch3/Ch3Test4.java b/src/test/java/com/example/urlshortener/ch3/Ch3Test4.java index a3e9ce3..4b2d2ee 100644 --- a/src/test/java/com/example/urlshortener/ch3/Ch3Test4.java +++ b/src/test/java/com/example/urlshortener/ch3/Ch3Test4.java @@ -24,7 +24,7 @@ class Ch3Test4 { @Test public void givenCreateShortenedUrlWhenLoadTheShortenedUrlThenExpectSameShortenedUrl() { - ShortenedUrl shortenedUrl = new ShortenedUrl("http://short.url/abc", "http://example.com/page1", LocalDateTime.now()); + ShortenedUrl shortenedUrl = new ShortenedUrl("abc", "http://example.com/page1", LocalDateTime.now()); ShortenedUrl savedShortenedUrl = shortenedUrlRepository.save(shortenedUrl); assertThat(shortenedUrlRepository.findByOriginUrl(savedShortenedUrl.getOriginUrl()).get().getId()).isEqualTo(savedShortenedUrl.getId()); @@ -41,7 +41,7 @@ public void givenDataAvailableWhenSortsFirstPageThenGetSortedData() { Condition sortedFirstCourseCondition = new Condition() { @Override public boolean matches(ShortenedUrl shortenedUrl) { - return shortenedUrl.getId() == 5L && shortenedUrl.getShortUrl().equals("http://short.url/mno"); + return shortenedUrl.getId() == 5L && shortenedUrl.getShortUrl().equals("mno"); } }; @@ -51,11 +51,11 @@ public boolean matches(ShortenedUrl shortenedUrl) { private void saveMockedShortenedUrls() { List shortenedUrls = List.of( - new ShortenedUrl("http://short.url/abc", "http://example.com/page1", LocalDateTime.parse("2024-04-01T10:00:00")), - new ShortenedUrl("http://short.url/def", "http://example.com/page2", LocalDateTime.parse("2024-04-02T12:00:00")), - new ShortenedUrl("http://short.url/ghi", "http://example.com/page3", LocalDateTime.parse("2024-04-03T14:00:00")), - new ShortenedUrl("http://short.url/jkl", "http://example.com/page4", LocalDateTime.parse("2024-04-04T16:00:00")), - new ShortenedUrl("http://short.url/mno", "http://example.com/page5", LocalDateTime.parse("2024-04-05T18:00:00")) + new ShortenedUrl("abc", "http://example.com/page1", LocalDateTime.parse("2024-04-01T10:00:00")), + new ShortenedUrl("def", "http://example.com/page2", LocalDateTime.parse("2024-04-02T12:00:00")), + new ShortenedUrl("ghi", "http://example.com/page3", LocalDateTime.parse("2024-04-03T14:00:00")), + new ShortenedUrl("jkl", "http://example.com/page4", LocalDateTime.parse("2024-04-04T16:00:00")), + new ShortenedUrl("mno", "http://example.com/page5", LocalDateTime.parse("2024-04-05T18:00:00")) ); shortenedUrlRepository.saveAll(shortenedUrls); diff --git a/src/test/java/com/example/urlshortener/ch3/Ch3Test5.java b/src/test/java/com/example/urlshortener/ch3/Ch3Test5.java index 9e964ec..93eb181 100644 --- a/src/test/java/com/example/urlshortener/ch3/Ch3Test5.java +++ b/src/test/java/com/example/urlshortener/ch3/Ch3Test5.java @@ -19,7 +19,7 @@ class Ch3Test5 { @Test public void givenShortenedUrlsWhenLoadShortenedUrlsWithQueryThenExpectCorrectShortenedUrlsDetails() { - ShortenedUrl shortenedUrl = new ShortenedUrl("http://short.url/abc", "http://example.com/page1", LocalDateTime.now()); + ShortenedUrl shortenedUrl = new ShortenedUrl("abc", "http://example.com/page1", LocalDateTime.now()); ShortenedUrl savedShortenedUrl = shortenedUrlRepository.save(shortenedUrl); assertThat(shortenedUrlRepository.findByShortUrlWithQuery(savedShortenedUrl.getShortUrl()).get().getOriginUrl()).isEqualTo("http://example.com/page1"); diff --git a/src/test/java/com/example/urlshortener/ch3/Ch3Test7.java b/src/test/java/com/example/urlshortener/ch3/Ch3Test7.java index f70f3bc..f4c34cd 100644 --- a/src/test/java/com/example/urlshortener/ch3/Ch3Test7.java +++ b/src/test/java/com/example/urlshortener/ch3/Ch3Test7.java @@ -53,16 +53,16 @@ public void givenAShortenedUrlAvailableWhenGetShortenedUrlByNameThenGetShortened Iterable result = shortenedUrlRepository.findShortenedUrlByOriginUrl("http://example.com/page1"); - assertThat(result).extracting("shortUrl").contains("http://short.url/abc"); + assertThat(result).extracting("shortUrl").contains("abc"); } private void saveMockedShortenedUrls() { List shortenedUrls = List.of( - new ShortenedUrl("http://short.url/abc", "http://example.com/page1", LocalDateTime.parse("2024-04-01T10:00:00")), - new ShortenedUrl("http://short.url/def", "http://example.com/page2", LocalDateTime.parse("2024-04-02T12:00:00")), - new ShortenedUrl("http://short.url/ghi", "http://example.com/page3", LocalDateTime.parse("2024-04-03T14:00:00")), - new ShortenedUrl("http://short.url/jkl", "http://example.com/page4", LocalDateTime.parse("2024-04-04T16:00:00")), - new ShortenedUrl("http://short.url/mno", "http://example.com/page5", LocalDateTime.parse("2024-04-05T18:00:00")) + new ShortenedUrl("abc", "http://example.com/page1", LocalDateTime.parse("2024-04-01T10:00:00")), + new ShortenedUrl("def", "http://example.com/page2", LocalDateTime.parse("2024-04-02T12:00:00")), + new ShortenedUrl("ghi", "http://example.com/page3", LocalDateTime.parse("2024-04-03T14:00:00")), + new ShortenedUrl("jkl", "http://example.com/page4", LocalDateTime.parse("2024-04-04T16:00:00")), + new ShortenedUrl("mno", "http://example.com/page5", LocalDateTime.parse("2024-04-05T18:00:00")) ); shortenedUrlRepository.saveAll(shortenedUrls);