|
1 | 1 | [[repositories.special-parameters]]
|
2 |
| -=== Special parameter handling |
| 2 | +=== Paging, Iterating Large Results, Sorting |
3 | 3 |
|
4 | 4 | To handle parameters in your query, define method parameters as already seen in the preceding examples.
|
5 | 5 | Besides that, the infrastructure recognizes certain specific types like `Pageable` and `Sort`, to apply pagination and sorting to your queries dynamically.
|
@@ -57,6 +57,82 @@ Rather, it restricts the query to look up only the given range of entities.
|
57 | 57 | NOTE: To find out how many pages you get for an entire query, you have to trigger an additional count query.
|
58 | 58 | By default, this query is derived from the query you actually trigger.
|
59 | 59 |
|
| 60 | + |
| 61 | +[[repositories.scrolling.guidance]] |
| 62 | +==== Which Method is Appropriate? |
| 63 | + |
| 64 | +The value provided by the Spring Data abstractions is perhaps best shown by the possible query method return types outlined in the following table below. |
| 65 | +The table shows which types you can return from a query method |
| 66 | + |
| 67 | +.Consuming Large Query Results |
| 68 | +[cols="1,2,2,3"] |
| 69 | +|=== |
| 70 | +| Method|Amount of Data Fetched|Query Structure|Constraints |
| 71 | + |
| 72 | +| <<repositories.collections-and-iterables,`List<T>`>> |
| 73 | +| All results. |
| 74 | +| Single query. |
| 75 | +| Query results can exhaust all memory. Fetching all data can be time-intensive. |
| 76 | + |
| 77 | +| <<repositories.collections-and-iterables.streamable,`Streamable<T>`>> |
| 78 | +| All results. |
| 79 | +| Single query. |
| 80 | +| Query results can exhaust all memory. Fetching all data can be time-intensive. |
| 81 | + |
| 82 | +| <<repositories.query-streaming,`Stream<T>`>> |
| 83 | +| Chunked (one-by-one or in batches) depending on `Stream` consumption. |
| 84 | +| Single query using typically cursors. |
| 85 | +| Streams must be closed after usage to avoid resource leaks. |
| 86 | + |
| 87 | +| `Flux<T>` |
| 88 | +| Chunked (one-by-one or in batches) depending on `Flux` consumption. |
| 89 | +| Single query using typically cursors. |
| 90 | +| Store module must provide reactive infrastructure. |
| 91 | + |
| 92 | +| `CloseableIterator<T>` |
| 93 | +| Chunked (one-by-one or in batches) depending on `CloseableIterator` consumption. |
| 94 | +| Single query using typically cursors. |
| 95 | +| `CloseableIterator` need to be closed after usage to avoid resource leaks. |
| 96 | + |
| 97 | +| `Slice<T>` |
| 98 | +| `Pageable.getPageSize() + 1` at `Pageable.getOffset()` |
| 99 | +| One to many queries fetching data starting at `Pageable.getOffset()` applying limiting. |
| 100 | +a| A `Slice` can only navigate to the next `Slice`. |
| 101 | + |
| 102 | +* `Slice` provides details whether there is more data to fetch. |
| 103 | +* Offset-based queries becomes inefficient when the offset is too large because the database still has to materialize the full result. |
| 104 | + |
| 105 | +ifdef::feature-scroll[] |
| 106 | +| Offset-based `Window<T>` |
| 107 | +| `limit + 1` at `OffsetScrollPosition.getOffset()` |
| 108 | +| One to many queries fetching data starting at `OffsetScrollPosition.getOffset()` applying limiting. |
| 109 | +a| A `Window` can only navigate to the next `Window`. |
| 110 | +endif::[] |
| 111 | + |
| 112 | +* `Window` provides details whether there is more data to fetch. |
| 113 | +* Offset-based queries becomes inefficient when the offset is too large because the database still has to materialize the full result. |
| 114 | + |
| 115 | +| `Page<T>` |
| 116 | +| `Pageable.getPageSize()` at `Pageable.getOffset()` |
| 117 | +| One to many queries starting at `Pageable.getOffset()` applying limiting. Additionally, `COUNT(…)` query to determine the total number of elements can be required. |
| 118 | +a| Often times, `COUNT(…)` queries are required that are costly. |
| 119 | + |
| 120 | +* Offset-based queries becomes inefficient when the offset is too large because the database still has to materialize the full result. |
| 121 | + |
| 122 | +ifdef::feature-scroll[] |
| 123 | +| Keyset-based `Window<T>` |
| 124 | +| `limit + 1` using a rewritten `WHERE` condition |
| 125 | +| One to many queries fetching data starting at `KeysetScrollPosition.getKeys()` applying limiting. |
| 126 | +a| A `Window` can only navigate to the next `Window`. |
| 127 | + |
| 128 | +* `Window` provides details whether there is more data to fetch. |
| 129 | +* Keyset-based queries require a proper index structure for efficient querying. |
| 130 | +* Most data stores do not work well when Keyset-based query results contain `null` values. |
| 131 | +* Results must expose all sorting keys in their results requiring projections to select potentially more properties than required for the actual projection. |
| 132 | +endif::[] |
| 133 | + |
| 134 | +|=== |
| 135 | + |
60 | 136 | [[repositories.paging-and-sorting]]
|
61 | 137 | ==== Paging and Sorting
|
62 | 138 |
|
@@ -102,6 +178,7 @@ ifdef::feature-scroll[]
|
102 | 178 | include::repositories-scrolling.adoc[]
|
103 | 179 | endif::[]
|
104 | 180 |
|
| 181 | + |
105 | 182 | [[repositories.limit-query-result]]
|
106 | 183 | === Limiting Query Results
|
107 | 184 |
|
|
0 commit comments