-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathquery-beans.html
More file actions
120 lines (107 loc) · 4.24 KB
/
Copy pathquery-beans.html
File metadata and controls
120 lines (107 loc) · 4.24 KB
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
<html>
<head>
<title>Query beans | Ebean</title>
<meta name="layout" content="_layout2/base-docs.html"/>
<meta name="bread1" content="Query" href="/docs/query/"/>
<meta name="bread2" content="Query beans" href="/docs/query/query-beans"/>
<#assign n0_docs="true">
<#assign n1_query="true">
<#assign querybeans="true">
</head>
<body>
<h2 id="querybeans">Query beans</h2>
<p>
Query beans are optional but they provide a nice way to write queries with <code>type safe
compile time checking</code>. They are also easy to use and learn with <code>IDE auto-completion</code>
on properties and expressions.
</p>
<p>
Query beans are generated using a Java annotation processing (<em>APT</em>) or
Kotlin annotation processing (<em>KAPT</em>).
</p>
<p>
For each entity a <em>query bean</em> is generated with the same name but prefixed with <code>Q</code>.
So for an entity bean called <em>Customer</em> there is a query bean generated called <em>QCustomer</em>.
</p>
<p>
When the entity bean model changes
the query beans are regenerated and as developers we get compile time checking on
our application queries - we get a compile time error if our queries are no longer
valid for the model.
</p>
<h5>Examples:</h5>
<pre content="java">
Contact contact =
new QContact() // Contact query bean
.email.equalTo("rob@foo.com") // type safe expression
.findOne(); // with IDE auto-completion
</pre>
<pre content="java">
List<|Customer> customers =
new QCustomer() // Customer query bean
.status.equalTo(Status.NEW)
.billingAddress.city.equalTo("Auckland") // joins automatically added
.contacts.isEmpty() // to support expressions
.findList();
</pre>
<h2 id="apt" class="art">APT / KAPT <em>(generating query beans)</em></h2>
<p>
To generate <code>Java</code> query beans we use the <em>io.ebean:querybean-generator</em>
java annotation processor and to generate <code>Kotlin</code> query beans we use
<em>io.ebean:kotlin-querybean-generator</em>.
</p>
<h4 id="maven" class="art">Generating with Maven</h4>
<p>
Refer to <a href="/docs/getting-started/maven">docs / getting-started / maven</a>
for details of how to generate query beans using maven.
</p>
<h4 id="gradle">Generating with Gradle</h4>
<p>
Refer to <a href="/docs/getting-started/gradle">docs / getting-started / gradle</a>
for details of how to generate query beans using gradle.
</p>
<h2 id="enhancement" class="art">Enhancement</h2>
<p>
Note that prior to version 12.1.8 we need to edit a <code>src/main/resources/ebean.mf</code>
manifest file to specify <code>querybean-packages</code> for the packages that should
be enhanced for query beans. This is no longer needed from 12.1.8 onwards.
</p>
<h5>Example (Pre 12.1.8)</h5>
<pre content="properties">
entity-packages: org.example.domain
transactional-packages: org.example
querybean-packages: org.example
</pre>
<h2 id="caveats" class="art">Caveat - refactor rename</h2>
<h3>Refactor rename entity bean</h3>
<p>
When we refactor rename an entity bean in an IDE the query beans we should trigger a <code>build all</code>.
This is because the query beans for the old bean names are kept around until the next <code>build all</code>.
</p>
<p>
Once we do a <code>build all</code> this will effectively delete the old query beans and generate the new ones.
At this point we get compiler errors for the queries that we need to adjust (use the new query bean names).
</p>
<h2 id="groovy">Groovy Spock</h2>
<p>
When using query beans with Groovy perhaps in Spock tests we need to use them inside a <code>@CompileStatic</code>
block.
</p>
<pre content="groovy">
@CompileStatic
static def findCount(String name) {
return new QDbSample().name.eq(name).findCount()
}
</pre>
<p>
Then we can use the helper method in our spock test like:
</p>
<pre content="groovy">
...
then:
// this line NPEs
findCount('fred') == 1
</pre>
<@next_edit "Where" "/docs/query/where" "/docs/query/query-beans.html"/>
</body>
</html>