-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfields2.html
More file actions
217 lines (212 loc) · 9.06 KB
/
fields2.html
File metadata and controls
217 lines (212 loc) · 9.06 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>exedio persistence - Field Reloaded Trail</title>
<meta name="keywords" content="Persistence, Java">
<meta name="description" content="persistence framework for java">
<link rel="stylesheet" href="cope.css">
</head>
<body>
<!-- HEADER -->
<div id="header_wrap" class="outer">
<header class="inner">
<a id="forkme_banner" href="https://github.com/exedio">View on GitHub</a>
<h1 id="project_title">exedio persistence</h1>
<h2 id="project_tagline">Persistence Framework for Java.</h2>
<a id="toplink" href="index.html">Go to top</a>
</header>
</div>
<!-- MAIN CONTENT -->
<div id="main_content_wrap" class="outer">
<section id="main_content" class="inner">
<h2>Field Reloaded Trail</h2>
<p>
While the <a href="fields.html">Field Trail</a>
covered the most fundamental fields only,
this trails shows you some more special ways to store data.
Although most of the features below are not fields in a formal sense
(means subclasses of class <a href="api/com/exedio/cope/Field.html">Field</a>)
you don't have to care about this until you want to develop such features yourself.
</p>
<h3 id="contents">Contents</h3>
<ul>
<li><a href="#hashes">Hashes</a></li>
<li><a href="#list">List Fields</a></li>
<li><a href="#map">Map Fields</a></li>
<li><a href="#dayfields">Day Fields</a></li>
<li><a href="#constraints">Check Constraints</a></li>
<li><a href="#further">Further Reading</a></li>
</ul>
<h3 id="hashes">Hashes</h3>
<p>
If you want to store a string encoded by a hash algorithm,
such as the password of the customer,
then put the following into class <code>Customer</code>:
</p>
<pre>
static final <a href="api/com/exedio/cope/pattern/MD5Hash.html">MD5Hash</a> password = new <a href="api/com/exedio/cope/pattern/MD5Hash.html#<init>()">MD5Hash</a>();
</pre>
<p>
The instrumentor will generate a method for checking the password
instead of a getter method:
</p>
<pre>
boolean checkPassword(String password)
{
return Customer.password.check(this, password);
}
</pre>
<p>
Using the super classes of <code>MD5Hash</code>
you can choose any hash algorithm provided by the java.security package
or even implement a custom algorithm.
</p>
<h3 id="list">List Fields</h3>
<p>
Sometimes you may want to store multiple values for an field,
such as multiple email addresses for the customer.
This can be achieved with <i>list fields</i>:
</p>
<pre>
static final <a href="api/com/exedio/cope/pattern/ListField.html">ListField</a><String> emails =
<a href="api/com/exedio/cope/pattern/ListField.html">ListField</a>.<a href="api/com/exedio/cope/pattern/ListField.html#create(com.exedio.cope.FunctionField)">create</a>(new StringField());
</pre>
<p>
Internally this is implemented by an extra table in the database,
so you can store lists of any size.
If you are sure, that the list cannot a exceed a certain size,
you may decide to use a <i>limited list field</i>:
</p>
<pre>
static final <a href="api/com/exedio/cope/pattern/LimitedListField.html">LimitedListField</a><String> emails =
<a href="api/com/exedio/cope/pattern/LimitedListField.html">LimitedListField</a>.<a href="api/com/exedio/cope/pattern/LimitedListField.html#create(com.exedio.cope.FunctionField,int)">create</a>(new StringField().<a href="api/com/exedio/cope/StringField.html#optional()">optional</a>(), 4);
</pre>
<p>
Internally there are 4 string fields used for storing the elements of the list.
If someone tries to store a list of more than 4 elements,
an exception is thrown.
</p>
<h3 id="map">Map Fields</h3>
<p>
Especially in international applications you may want to store multiple field values,
such as one price of a product for each country or one description for each language.
The following example specifies the latter:
</p>
<pre>
static final <a href="api/com/exedio/cope/pattern/MapField.html">MapField</a><Language,String> description =
<a href="api/com/exedio/cope/pattern/MapField.html">MapField</a>.<a href="api/com/exedio/cope/pattern/MapField.html#create(com.exedio.cope.FunctionField,com.exedio.cope.FunctionField)">create</a>(newItemField(Language.class),
new StringField());
</pre>
<p>
The instrumentor will create appropriate methods for accessing the <i>field map</i>:
</p>
<pre>
String getDescription(Language k)
{
return Product.description.get(this, k);
}
void setDescription(Language k, String description)
{
Product.description.set(this, k, description);
}
</pre>
<p>
This example assumes, that there is already a persistent item <code>Language</code>.
If you decide to use use a fixed set of languages in your application,
you may use an enum instead:
</p>
<pre>
static enum Language { DE, EN, PL; }
static final <a href="api/com/exedio/cope/pattern/MapField.html">MapField</a><Language,String> description =
<a href="api/com/exedio/cope/pattern/MapField.html">MapField</a>.<a href="api/com/exedio/cope/pattern/MapField.html#create(com.exedio.cope.FunctionField,com.exedio.cope.FunctionField)">create</a>(newEnumField(Language.class),
new StringField());
</pre>
<p>
As with <i>list fields</i> this is implemented by an extra table in the database,
so you can store maps of any size.
If the key space of the map is limited to an enum,
you may decide to use a <i>enum map field</i> instead:
</p>
<pre>
static enum Language { DE, EN, PL; }
static final <a href="api/com/exedio/cope/pattern/EnumMapField.html">EnumMapField</a><Language,String> description =
<a href="api/com/exedio/cope/pattern/EnumMapField.html">EnumMapField</a>.<a href="api/com/exedio/cope/pattern/EnumMapField.html#create(java.lang.Class,com.exedio.cope.FunctionField)">create</a>(Language.class,
new StringField().<a href="api/com/exedio/cope/StringField.html#optional()">optional</a>());
</pre>
<p>
Internally three string fields
<code>nameDE</code>, <code>nameEN</code>, <code>namePL</code>
are used for storing the values of the map.
</p>
<h3 id="dayfields">Day Fields</h3>
<p>
Class <a href="api/com/exedio/cope/DateField.html">DateField</a>
already stores time stamps with millisecond precision.
However, sometimes you just want to store a day.
Millisecond precision is then just an additional source for mistakes.
Since the java runtime library does not provide a value class for this,
exedio persistence has to introduce it's own <a href="api/com/exedio/cope/util/Day.html">Day</a>.
To define a <i>day field</i> within a type write:
</p>
<pre>
static final <a href="api/com/exedio/cope/DayField.html">DayField</a> dateOfBirth = new <a href="api/com/exedio/cope/DayField.html#<init>()">DayField</a>();
</pre>
<h3 id="constraints">Check Constraints</h3>
<p>
exedio persistence makes it easy to define check constraints for persistent fields.
Here an example with a string field, that holds at most 40 characters
and an integer field that must not be negative:
</p>
<pre>
class Customer extends Item
{
static final <a href="api/com/exedio/cope/StringField.html">StringField</a> email =
new <a href="api/com/exedio/cope/StringField.html#<init>()">StringField</a>().<b><a href="api/com/exedio/cope/StringField.html#lengthMax(int)">lengthMax</a>(40)</b>;
static final <a href="api/com/exedio/cope/IntegerField.html">IntegerField</a> loginCounter =
new <a href="api/com/exedio/cope/IntegerField.html#<init>()">IntegerField</a>().<b><a href="api/com/exedio/cope/IntegerField.html#min(int)">min</a>(0)</b>;
}
</pre>
<p>
Trying to violate such a constraint when modifying or creating a Customer causes a
<a href="api/com/exedio/cope/StringLengthViolationException.html">StringLengthViolationException</a> or
<a href="api/com/exedio/cope/IntegerRangeViolationException.html">IntegerRangeViolationException</a> to be thrown.
</p>
<h3 id="further">Further Reading</h3>
<p>
This was the advanced field trail of the tour.
You may now proceed to trails:
</p>
<ul>
<li>
<a href="transactions.html">Transactions Trail</a>
tells you how to use transactions in exedio persistence.
</li>
<li>
<a href="searching.html">Searching Trail</a>
gives you an introduction into the searching capabilities of exedio persistence.
</li>
<li>
<a href="webapplications.html">Web Application Trail</a>
shows you the little differences when using the framework within a web container.
</li>
</ul>
</section>
</div>
<!-- FOOTER -->
<div id="footer_wrap" class="outer">
<footer class="inner">
<p>
Maintained by
<a href="https://www.exedio.com/" target="_top">exedio</a>
Gesellschaft für Softwareentwicklung mbH.
</p>
<a href="https://validator.w3.org/check?uri=referer" class="validhtml">Valid HTML5</a>
<p>
Slate theme by <a href="https://github.com/jasoncostello">Jason Costello</a>.
Published with <a href="https://pages.github.com">GitHub Pages</a>.
</p>
</footer>
</div>
</body>
</html>