-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathQuery.java
144 lines (139 loc) · 6.63 KB
/
Query.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* Copyright (c) 2022,2024 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.data.repository;
import jakarta.data.Sort;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>Annotates a repository method as a query method, specifying a query written in Jakarta Data Query Language (JDQL)
* or in Jakarta Persistence Query Language (JPQL). A Jakarta Data provider is not required to support the complete JPQL
* language, which targets relational data stores. However, a given provider might offer features of JPQL which go
* beyond the subset required by JDQL, or might even offer vendor-specific extensions to JDQL which target particular
* capabilities of the target data store technology. Such extensions come with no guarantee of portability between
* providers, nor between databases.</p>
*
* <p>The required {@link #value} member specifies the JDQL or JPQL query as a string.</p>
*
* <p>For {@code select} statements, the return type of the query method must be consistent with the type returned by
* the query. For {@code update} or {@code delete} statements, it must be {@code void}, {@code int} or {@code long}.</p>
*
* <p>Compared to SQL, JDQL allows an abbreviated syntax for {@code select} statements:</p>
* <ul>
* <li>The {@code from} clause is optional in JDQL. When it is missing, the queried entity is determined by the return
* type of the repository method, or, if the return type is not an entity type, by the primary entity type of the
* repository.</li>
* <li>The {@code select} clause is optional in both JDQL and JPQL. When it is missing, the query returns the queried
* entity.</li>
* </ul>
*
* <p>A query might involve:</p>
* <ul>
* <li>named parameters of form {@code :name} where the labels {@code name} are legal Java identifiers, or </li>
* <li>ordinal parameters of form {@code ?n} where the labels {@code n} are sequential positive integers starting
* from {@code 1}.</li>
* </ul>
* <p>A given query must not mix named and ordinal parameters.</p>
*
* <p>Each parameter of an annotated query method must either:</p>
* <ul>
* <li>have exactly the same name (the parameter name in the Java source, or a name assigned by {@link Param @Param})
* and type as a named parameter of the query,</li>
* <li>have exactly the same type and position within the parameter list of the method as a positional parameter of the
* query, or</li>
* <li>be of type {@code Limit}, {@code Order}, {@code PageRequest}, or {@code Sort}.</li>
* </ul>
*
* <p>The {@link Param} annotation associates a method parameter with a named parameter. The {@code Param} annotation is
* unnecessary when the method parameter name matches the name of a named parameter and the application is compiled with
* the {@code -parameters} compiler option making parameter names available at runtime.</p>
*
* <p>A method parameter is associated with an ordinal parameter by its position in the method parameter list. The first
* parameter of the method is associated with the ordinal parameter {@code ?1}.</p>
*
* <p>For example,</p>
*
* <pre>
* @Repository
* public interface People extends CrudRepository<Person, Long> {
*
* // JDQL with positional parameters
* @Query("where firstName = ?1 and lastName = ?2")
* List<Person> byName(String first, String last);
*
* // JDQL with a named parameter
* @Query("where firstName || ' ' || lastName like :pattern")
* List<Person> byName(String pattern);
*
* // JPQL using a positional parameter
* @Query("from Person where extract(year from birthdate) = ?1")
* List<Person> bornIn(int year);
*
* // JPQL using named parameters
* @Query("select distinct name from Person " +
* "where length(name) >= :min and length(name) <= :max")
* Page<String> namesOfLength(@Param("min") int minLength,
* @Param("max") int maxLength,
* PageRequest pageRequest,
* Order<Person> order);
*
* ...
* }
* </pre>
*
* <p>A method annotated with {@code @Query} must return one of the following types:</p>
* <ul>
* <li>the query result type {@code R}, when the query returns a single result,</li>
* <li>{@code Optional<R>}, when the query returns at most a single result,</li>
* <li>an array type {@code R[]},
* <li>{@code List<R>},</li>
* <li>{@code Stream<R>}, or</li>
* <li>{@code Page<R>} or {@code CursoredPage<R>}.</li>
* </ul>
* <p>The method returns an object for every query result.</p>
* <ul>
* <li>If the return type of the annotated method is {@code R} or {@code Optional<R>} and more than one record satisfies
* the query restriction, the method must throw {@link jakarta.data.exceptions.NonUniqueResultException}.</li>
* <li>If the return type of the annotated method is {@code R} and no record satisfies the query restriction, the method
* must throw {@link jakarta.data.exceptions.EmptyResultException}.</li>
* </ul>
*
* <p>Annotations such as {@code @Find}, {@code @Query}, {@code @Insert}, {@code @Update}, {@code @Delete}, and
* {@code @Save} are mutually-exclusive. A given method of a repository interface may have at most one {@code @Find}
* annotation, lifecycle annotation, or query annotation.
*
* @see Param
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Query {
/**
* <p>Specifies the query executed by the annotated repository method,
* in JDQL or JPQL.</p>
*
* <p>If the annotated repository method accepts other forms of sorting
* (such as a parameter of type {@link Sort}), it is the responsibility
* of the application programmer to compose the query so that an
* {@code ORDER BY} clause can be validly appended to the text of the
* query.</p>
*
* @return the query to be executed when the annotated method is called.
*/
String value();
}