Scroll API Implementation (#14435)
Co-authored-by: technoddy <mail.technoddy@gmail.com>
This commit is contained in:
		
							parent
							
								
									787ed13597
								
							
						
					
					
						commit
						aae5f7dc38
					
				
							
								
								
									
										63
									
								
								persistence-modules/spring-boot-persistence-4/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								persistence-modules/spring-boot-persistence-4/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||
|          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <groupId>com.baeldung.boot.persistence</groupId> | ||||
|     <artifactId>spring-boot-persistence-4</artifactId> | ||||
|     <version>0.0.1-SNAPSHOT</version> | ||||
|     <name>spring-boot-persistence-4</name> | ||||
| 
 | ||||
|     <dependencyManagement> | ||||
|         <dependencies> | ||||
|             <dependency> | ||||
|                 <groupId>org.junit</groupId> | ||||
|                 <artifactId>junit-bom</artifactId> | ||||
|                 <version>${junit-jupiter.version}</version> | ||||
|                 <type>pom</type> | ||||
|                 <scope>import</scope> | ||||
|             </dependency> | ||||
|             <dependency> | ||||
|                 <groupId>org.springframework.boot</groupId> | ||||
|                 <artifactId>spring-boot-dependencies</artifactId> | ||||
|                 <version>${spring.boot.dependencies}</version> | ||||
|                 <type>pom</type> | ||||
|                 <scope>import</scope> | ||||
|             </dependency> | ||||
|         </dependencies> | ||||
|     </dependencyManagement> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-data-jpa</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.h2database</groupId> | ||||
|             <artifactId>h2</artifactId> | ||||
|             <scope>runtime</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <groupId>org.springframework.boot</groupId> | ||||
|                 <artifactId>spring-boot-maven-plugin</artifactId> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
| 
 | ||||
|     <properties> | ||||
|         <spring.boot.dependencies>3.1.0</spring.boot.dependencies> | ||||
|         <junit-jupiter.version>5.9.3</junit-jupiter.version> | ||||
|         <maven.compiler.source>17</maven.compiler.source> | ||||
|         <maven.compiler.target>17</maven.compiler.target> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
| @ -0,0 +1,11 @@ | ||||
| package com.baeldung.scrollapi; | ||||
| 
 | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| 
 | ||||
| @SpringBootApplication | ||||
| public class ScrollAPIApplication { | ||||
|     public static void main(String[] args) { | ||||
|         SpringApplication.run(ScrollAPIApplication.class, args); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,53 @@ | ||||
| package com.baeldung.scrollapi.entity; | ||||
| 
 | ||||
| import jakarta.persistence.*; | ||||
| 
 | ||||
| @Entity | ||||
| @Table(name = "BOOK_REVIEWS") | ||||
| public class BookReview { | ||||
| 
 | ||||
|     @Id | ||||
|     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "book_reviews_reviews_id_seq") | ||||
|     @SequenceGenerator(name = "book_reviews_reviews_id_seq", sequenceName = "book_reviews_reviews_id_seq", allocationSize = 1) | ||||
|     private Long reviewsId; | ||||
|     private String userId; | ||||
|     private String isbn; | ||||
|     private String bookRating; | ||||
| 
 | ||||
|     public Long getReviewsId() { | ||||
|         return reviewsId; | ||||
|     } | ||||
| 
 | ||||
|     public void setReviewsId(Long reviewsId) { | ||||
|         this.reviewsId = reviewsId; | ||||
|     } | ||||
| 
 | ||||
|     public String getUserId() { | ||||
|         return userId; | ||||
|     } | ||||
| 
 | ||||
|     public void setUserId(String userId) { | ||||
|         this.userId = userId; | ||||
|     } | ||||
| 
 | ||||
|     public String getIsbn() { | ||||
|         return isbn; | ||||
|     } | ||||
| 
 | ||||
|     public void setIsbn(String isbn) { | ||||
|         this.isbn = isbn; | ||||
|     } | ||||
| 
 | ||||
|     public String getBookRating() { | ||||
|         return bookRating; | ||||
|     } | ||||
| 
 | ||||
|     public void setBookRating(String bookRating) { | ||||
|         this.bookRating = bookRating; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return "BookReview{" + "reviewsId=" + reviewsId + ", userId='" + userId + '\'' + ", isbn='" + isbn + '\'' + ", bookRating='" + bookRating + '\'' + '}'; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,16 @@ | ||||
| package com.baeldung.scrollapi.repository; | ||||
| 
 | ||||
| import org.springframework.data.domain.KeysetScrollPosition; | ||||
| import org.springframework.data.domain.OffsetScrollPosition; | ||||
| import org.springframework.data.domain.Window; | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.repository.Repository; | ||||
| 
 | ||||
| import com.baeldung.scrollapi.entity.BookReview; | ||||
| 
 | ||||
| public interface BookRepository extends JpaRepository<BookReview, Long> { | ||||
| 
 | ||||
|     Window<BookReview> findFirst5ByBookRating(String bookRating, OffsetScrollPosition position); | ||||
| 
 | ||||
|     Window<BookReview> findFirst5ByBookRating(String bookRating, KeysetScrollPosition position); | ||||
| } | ||||
| @ -0,0 +1,53 @@ | ||||
| package com.baeldung.scrollapi.service; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.data.domain.KeysetScrollPosition; | ||||
| import org.springframework.data.domain.OffsetScrollPosition; | ||||
| import org.springframework.data.domain.ScrollPosition; | ||||
| import org.springframework.data.domain.Window; | ||||
| import org.springframework.data.support.WindowIterator; | ||||
| import org.springframework.stereotype.Service; | ||||
| 
 | ||||
| import com.baeldung.scrollapi.entity.BookReview; | ||||
| import com.baeldung.scrollapi.repository.BookRepository; | ||||
| 
 | ||||
| @Service | ||||
| public class BookLogic { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private BookRepository bookRepository; | ||||
| 
 | ||||
|     public List<BookReview> getBooksUsingOffset(String rating) { | ||||
|         OffsetScrollPosition offset = ScrollPosition.offset(); | ||||
| 
 | ||||
|         Window<BookReview> bookReviews = bookRepository.findFirst5ByBookRating(rating, offset); | ||||
|         List<BookReview> bookReviewsResult = new ArrayList<>(); | ||||
|         do { | ||||
|             bookReviews.forEach(bookReviewsResult::add); | ||||
|             bookReviews = bookRepository.findFirst5ByBookRating(rating, (OffsetScrollPosition) bookReviews.positionAt(bookReviews.size() - 1)); | ||||
|         } while (!bookReviews.isEmpty() && bookReviews.hasNext()); | ||||
| 
 | ||||
|         return bookReviewsResult; | ||||
|     } | ||||
| 
 | ||||
|     public List<BookReview> getBooksUsingOffSetFilteringAndWindowIterator(String rating) { | ||||
|         WindowIterator<BookReview> bookReviews = WindowIterator.of(position -> bookRepository.findFirst5ByBookRating("3.5", (OffsetScrollPosition) position)) | ||||
|             .startingAt(ScrollPosition.offset()); | ||||
|         List<BookReview> bookReviewsResult = new ArrayList<>(); | ||||
| 
 | ||||
|         bookReviews.forEachRemaining(bookReviewsResult::add); | ||||
|         return bookReviewsResult; | ||||
|     } | ||||
| 
 | ||||
|     public List<BookReview> getBooksUsingKeySetFiltering(String rating) { | ||||
|         WindowIterator<BookReview> bookReviews = WindowIterator.of(position -> bookRepository.findFirst5ByBookRating(rating, (KeysetScrollPosition) position)) | ||||
|             .startingAt(ScrollPosition.keyset()); | ||||
|         List<BookReview> bookReviewsResult = new ArrayList<>(); | ||||
| 
 | ||||
|         bookReviews.forEachRemaining(bookReviewsResult::add); | ||||
|         return bookReviewsResult; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,4 @@ | ||||
| 
 | ||||
| logging.level.org.hibernate: | ||||
|   SQL: DEBUG | ||||
|   type.descriptor.sql.BasicBinder: TRACE | ||||
| @ -0,0 +1,73 @@ | ||||
| package com.baeldung.boot.scrollapi.service; | ||||
| 
 | ||||
| import static org.assertj.core.api.AssertionsForClassTypes.assertThat; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.UUID; | ||||
| import java.util.stream.IntStream; | ||||
| 
 | ||||
| import org.junit.jupiter.api.AfterEach; | ||||
| import org.junit.jupiter.api.BeforeEach; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| 
 | ||||
| import com.baeldung.scrollapi.ScrollAPIApplication; | ||||
| import com.baeldung.scrollapi.entity.BookReview; | ||||
| import com.baeldung.scrollapi.repository.BookRepository; | ||||
| import com.baeldung.scrollapi.service.BookLogic; | ||||
| 
 | ||||
| @SpringBootTest(classes = ScrollAPIApplication.class) | ||||
| class BookLogicUnitTest { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private BookRepository bookRepository; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private BookLogic bookLogic; | ||||
| 
 | ||||
|     @BeforeEach | ||||
|     public void beforeEach() { | ||||
|         IntStream.rangeClosed(1, 5) | ||||
|             .forEach(i -> insertBookReview()); | ||||
|     } | ||||
| 
 | ||||
|     @AfterEach | ||||
|     public void afterEach() { | ||||
|         bookRepository.deleteAll(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenBookReviewInTable_whenGetBooksUsingOffset_returnsBookReviews() { | ||||
|         List<BookReview> bookReviews = bookLogic.getBooksUsingOffset("3.5"); | ||||
|         assertThat(bookReviews.size()).isEqualTo(5); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenBookReviewInTable_whenGetBooksUsingOffSetFilteringAndWindowIterator_returnsBookReviews() { | ||||
|         List<BookReview> bookReviews = bookLogic.getBooksUsingOffSetFilteringAndWindowIterator("3.5"); | ||||
|         assertThat(bookReviews.size()).isEqualTo(5); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenBookReviewInTable_whenGetBooksUsingKeySetFiltering_returnsBookReviews() { | ||||
|         List<BookReview> bookReviews = bookLogic.getBooksUsingKeySetFiltering("3.5"); | ||||
|         assertThat(bookReviews.size()).isEqualTo(5); | ||||
|     } | ||||
| 
 | ||||
|     private void insertBookReview() { | ||||
|         BookReview bookReview = getBookReview(); | ||||
|         bookRepository.save(bookReview); | ||||
|     } | ||||
| 
 | ||||
|     private static BookReview getBookReview() { | ||||
|         BookReview bookReview = new BookReview(); | ||||
|         String seed = UUID.randomUUID() | ||||
|             .toString(); | ||||
|         bookReview.setIsbn("isbn" + seed); | ||||
|         bookReview.setBookRating("3.5"); | ||||
|         bookReview.setUserId(seed); | ||||
| 
 | ||||
|         return bookReview; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,5 @@ | ||||
| # spring.datasource.x | ||||
| spring.datasource.driver-class-name=org.h2.Driver | ||||
| spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 | ||||
| spring.datasource.username=sa | ||||
| spring.datasource.password=sa | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user