Skip to content

Commit 92fdc9e

Browse files
committed
Adds List based repository interfaces.
This introduces the interfaces * `ListCrudRepository` * `ListQuerydslPredicateExecutor` * `ListQueryByExampleExecutor` They return `List` instead of `Iterable` when returning multiple entities. They can be used in the same way the interfaces without the `List` prefix can be used. Closes #2535.
1 parent a80ea15 commit 92fdc9e

File tree

4 files changed

+362
-1
lines changed

4 files changed

+362
-1
lines changed

src/main/asciidoc/repositories.adoc

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ For detailed information on the specific features of your module, see the chapte
2323
The central interface in the Spring Data repository abstraction is `Repository`.
2424
It takes the domain class to manage as well as the ID type of the domain class as type arguments.
2525
This interface acts primarily as a marker interface to capture the types to work with and to help you to discover interfaces that extend this one.
26-
The https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html[`CrudRepository`] interface provides sophisticated CRUD functionality for the entity class that is being managed.
26+
The https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html[`CrudRepository`] and https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/ListCrudRepository.html[`ListCrudRepository`] interfaces provide sophisticated CRUD functionality for the entity class that is being managed.
2727

2828
[[repositories.repository]]
2929
.`CrudRepository` Interface
@@ -55,6 +55,8 @@ public interface CrudRepository<T, ID> extends Repository<T, ID> {
5555
<6> Indicates whether an entity with the given ID exists.
5656
====
5757

58+
`ListCrudRepository` offers equivalent methods, but they return `List` where the `CrudRepository` methods return an `Iterable`.
59+
5860
NOTE: We also provide persistence technology-specific abstractions, such as `JpaRepository` or `MongoRepository`.
5961
Those interfaces extend `CrudRepository` and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces such as `CrudRepository`.
6062

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.querydsl;
17+
18+
import java.util.List;
19+
import java.util.Optional;
20+
import java.util.function.Function;
21+
22+
import org.springframework.data.domain.Page;
23+
import org.springframework.data.domain.Pageable;
24+
import org.springframework.data.domain.Sort;
25+
import org.springframework.data.repository.query.FluentQuery;
26+
27+
import com.querydsl.core.types.OrderSpecifier;
28+
import com.querydsl.core.types.Predicate;
29+
30+
/**
31+
* Interface to allow execution of QueryDsl {@link Predicate} instances.This identical to *
32+
* {@link QuerydslPredicateExecutor} but returns {@link List} instead of {@link Iterable} where applicable.
33+
*
34+
* @author Jens Schauder
35+
* @since 3.0
36+
* @see QuerydslPredicateExecutor
37+
*/
38+
public interface ListQuerydslPredicateExecutor<T> {
39+
40+
/**
41+
* Returns a single entity matching the given {@link Predicate} or {@link Optional#empty()} if none was found.
42+
*
43+
* @param predicate must not be {@literal null}.
44+
* @return a single entity matching the given {@link Predicate} or {@link Optional#empty()} if none was found.
45+
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the predicate yields more than one
46+
* result.
47+
*/
48+
Optional<T> findOne(Predicate predicate);
49+
50+
/**
51+
* Returns all entities matching the given {@link Predicate}. In case no match could be found an empty {@link List} is
52+
* returned.
53+
*
54+
* @param predicate must not be {@literal null}.
55+
* @return all entities matching the given {@link Predicate}.
56+
*/
57+
List<T> findAll(Predicate predicate);
58+
59+
/**
60+
* Returns all entities matching the given {@link Predicate} applying the given {@link Sort}. In case no match could
61+
* be found an empty {@link List} is returned.
62+
*
63+
* @param predicate must not be {@literal null}.
64+
* @param sort the {@link Sort} specification to sort the results by, may be {@link Sort#unsorted()}, must not be
65+
* {@literal null}.
66+
* @return all entities matching the given {@link Predicate}.
67+
*/
68+
List<T> findAll(Predicate predicate, Sort sort);
69+
70+
/**
71+
* Returns all entities matching the given {@link Predicate} applying the given {@link OrderSpecifier}s. In case no
72+
* match could be found an empty {@link List} is returned.
73+
*
74+
* @param predicate must not be {@literal null}.
75+
* @param orders the {@link OrderSpecifier}s to sort the results by, must not be {@literal null}.
76+
* @return all entities matching the given {@link Predicate} applying the given {@link OrderSpecifier}s.
77+
*/
78+
List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders);
79+
80+
/**
81+
* Returns all entities ordered by the given {@link OrderSpecifier}s.
82+
*
83+
* @param orders the {@link OrderSpecifier}s to sort the results by, must not be {@literal null}.
84+
* @return all entities ordered by the given {@link OrderSpecifier}s.
85+
*/
86+
List<T> findAll(OrderSpecifier<?>... orders);
87+
88+
/**
89+
* Returns a {@link Page} of entities matching the given {@link Predicate}. In case no match could be found, an empty
90+
* {@link Page} is returned.
91+
*
92+
* @param predicate must not be {@literal null}.
93+
* @param pageable may be {@link Pageable#unpaged()}, must not be {@literal null}.
94+
* @return a {@link Page} of entities matching the given {@link Predicate}.
95+
*/
96+
Page<T> findAll(Predicate predicate, Pageable pageable);
97+
98+
/**
99+
* Returns the number of instances matching the given {@link Predicate}.
100+
*
101+
* @param predicate the {@link Predicate} to count instances for, must not be {@literal null}.
102+
* @return the number of instances matching the {@link Predicate}.
103+
*/
104+
long count(Predicate predicate);
105+
106+
/**
107+
* Checks whether the data store contains elements that match the given {@link Predicate}.
108+
*
109+
* @param predicate the {@link Predicate} to use for the existence check, must not be {@literal null}.
110+
* @return {@literal true} if the data store contains elements that match the given {@link Predicate}.
111+
*/
112+
boolean exists(Predicate predicate);
113+
114+
/**
115+
* Returns entities matching the given {@link Predicate} applying the {@link Function queryFunction} that defines the
116+
* query and its result type.
117+
*
118+
* @param predicate must not be {@literal null}.
119+
* @param queryFunction the query function defining projection, sorting, and the result type
120+
* @return all entities matching the given {@link Predicate}.
121+
*/
122+
<S extends T, R> R findBy(Predicate predicate, Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction);
123+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* Copyright 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.repository;
17+
18+
import java.util.List;
19+
import java.util.Optional;
20+
21+
/**
22+
* Interface for generic CRUD operations on a repository for a specific type. This identical to {@link CrudRepository}
23+
* but returns {@link List} instead of {@link Iterable} where applicable.
24+
*
25+
* @author Jens Schauder
26+
* @see CrudRepository
27+
* @since 3.0
28+
*/
29+
@NoRepositoryBean
30+
public interface ListCrudRepository<T, ID> extends Repository<T, ID> {
31+
32+
/**
33+
* Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
34+
* entity instance completely.
35+
*
36+
* @param entity must not be {@literal null}.
37+
* @return the saved entity; will never be {@literal null}.
38+
* @throws IllegalArgumentException in case the given {@literal entity} is {@literal null}.
39+
*/
40+
<S extends T> S save(S entity);
41+
42+
/**
43+
* Saves all given entities.
44+
*
45+
* @param entities must not be {@literal null} nor must it contain {@literal null}.
46+
* @return the saved entities; will never be {@literal null}. The returned {@literal Iterable} will have the same size
47+
* as the {@literal Iterable} passed as an argument.
48+
* @throws IllegalArgumentException in case the given {@link Iterable entities} or one of its entities is
49+
* {@literal null}.
50+
*/
51+
<S extends T> List<S> saveAll(Iterable<S> entities);
52+
53+
/**
54+
* Retrieves an entity by its id.
55+
*
56+
* @param id must not be {@literal null}.
57+
* @return the entity with the given id or {@literal Optional#empty()} if none found.
58+
* @throws IllegalArgumentException if {@literal id} is {@literal null}.
59+
*/
60+
Optional<T> findById(ID id);
61+
62+
/**
63+
* Returns whether an entity with the given id exists.
64+
*
65+
* @param id must not be {@literal null}.
66+
* @return {@literal true} if an entity with the given id exists, {@literal false} otherwise.
67+
* @throws IllegalArgumentException if {@literal id} is {@literal null}.
68+
*/
69+
boolean existsById(ID id);
70+
71+
/**
72+
* Returns all instances of the type.
73+
*
74+
* @return all entities
75+
*/
76+
List<T> findAll();
77+
78+
/**
79+
* Returns all instances of the type {@code T} with the given IDs.
80+
* <p>
81+
* If some or all ids are not found, no entities are returned for these IDs.
82+
* <p>
83+
* Note that the order of elements in the result is not guaranteed.
84+
*
85+
* @param ids must not be {@literal null} nor contain any {@literal null} values.
86+
* @return guaranteed to be not {@literal null}. The size can be equal or less than the number of given
87+
* {@literal ids}.
88+
* @throws IllegalArgumentException in case the given {@link Iterable ids} or one of its items is {@literal null}.
89+
*/
90+
List<T> findAllById(Iterable<ID> ids);
91+
92+
/**
93+
* Returns the number of entities available.
94+
*
95+
* @return the number of entities.
96+
*/
97+
long count();
98+
99+
/**
100+
* Deletes the entity with the given id.
101+
*
102+
* @param id must not be {@literal null}.
103+
* @throws IllegalArgumentException in case the given {@literal id} is {@literal null}
104+
*/
105+
void deleteById(ID id);
106+
107+
/**
108+
* Deletes a given entity.
109+
*
110+
* @param entity must not be {@literal null}.
111+
* @throws IllegalArgumentException in case the given entity is {@literal null}.
112+
*/
113+
void delete(T entity);
114+
115+
/**
116+
* Deletes all instances of the type {@code T} with the given IDs.
117+
*
118+
* @param ids must not be {@literal null}. Must not contain {@literal null} elements.
119+
* @throws IllegalArgumentException in case the given {@literal ids} or one of its elements is {@literal null}.
120+
*/
121+
void deleteAllById(Iterable<? extends ID> ids);
122+
123+
/**
124+
* Deletes the given entities.
125+
*
126+
* @param entities must not be {@literal null}. Must not contain {@literal null} elements.
127+
* @throws IllegalArgumentException in case the given {@literal entities} or one of its entities is {@literal null}.
128+
*/
129+
void deleteAll(Iterable<? extends T> entities);
130+
131+
/**
132+
* Deletes all entities managed by the repository.
133+
*/
134+
void deleteAll();
135+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.repository.query;
17+
18+
import java.util.List;
19+
import java.util.Optional;
20+
import java.util.function.Function;
21+
22+
import org.springframework.data.domain.Example;
23+
import org.springframework.data.domain.Page;
24+
import org.springframework.data.domain.Pageable;
25+
import org.springframework.data.domain.Sort;
26+
27+
/**
28+
* Interface to allow execution of Query by Example {@link Example} instances. This identical to
29+
* {@link QueryByExampleExecutor} but returns {@link List} instead of {@link Iterable} where applicable.
30+
*
31+
* @param <T> the type of entity for which this executor acts on.
32+
* @author Jens Schauder
33+
* @since 3.0
34+
* @see QueryByExampleExecutor
35+
*/
36+
public interface ListQueryByExampleExecutor<T> {
37+
38+
/**
39+
* Returns a single entity matching the given {@link Example} or {@link Optional#empty()} if none was found.
40+
*
41+
* @param example must not be {@literal null}.
42+
* @return a single entity matching the given {@link Example} or {@link Optional#empty()} if none was found.
43+
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the Example yields more than one result.
44+
*/
45+
<S extends T> Optional<S> findOne(Example<S> example);
46+
47+
/**
48+
* Returns all entities matching the given {@link Example}. In case no match could be found an empty {@link List} is
49+
* returned.
50+
*
51+
* @param example must not be {@literal null}.
52+
* @return all entities matching the given {@link Example}.
53+
*/
54+
<S extends T> List<S> findAll(Example<S> example);
55+
56+
/**
57+
* Returns all entities matching the given {@link Example} applying the given {@link Sort}. In case no match could be
58+
* found an empty {@link List} is returned.
59+
*
60+
* @param example must not be {@literal null}.
61+
* @param sort the {@link Sort} specification to sort the results by, must not be {@literal null}.
62+
* @return all entities matching the given {@link Example}.
63+
*/
64+
<S extends T> List<S> findAll(Example<S> example, Sort sort);
65+
66+
/**
67+
* Returns a {@link Page} of entities matching the given {@link Example}. In case no match could be found, an empty
68+
* {@link Page} is returned.
69+
*
70+
* @param example must not be {@literal null}.
71+
* @param pageable can be {@literal null}.
72+
* @return a {@link Page} of entities matching the given {@link Example}.
73+
*/
74+
<S extends T> Page<S> findAll(Example<S> example, Pageable pageable);
75+
76+
/**
77+
* Returns the number of instances matching the given {@link Example}.
78+
*
79+
* @param example the {@link Example} to count instances for. Must not be {@literal null}.
80+
* @return the number of instances matching the {@link Example}.
81+
*/
82+
<S extends T> long count(Example<S> example);
83+
84+
/**
85+
* Checks whether the data store contains elements that match the given {@link Example}.
86+
*
87+
* @param example the {@link Example} to use for the existence check. Must not be {@literal null}.
88+
* @return {@literal true} if the data store contains elements that match the given {@link Example}.
89+
*/
90+
<S extends T> boolean exists(Example<S> example);
91+
92+
/**
93+
* Returns entities matching the given {@link Example} applying the {@link Function queryFunction} that defines the
94+
* query and its result type.
95+
*
96+
* @param example must not be {@literal null}.
97+
* @param queryFunction the query function defining projection, sorting, and the result type
98+
* @return all entities matching the given {@link Example}.
99+
*/
100+
<S extends T, R> R findBy(Example<S> example, Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction);
101+
}

0 commit comments

Comments
 (0)