You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/source/en/entity-sequence.md
+20-30Lines changed: 20 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,16 +10,17 @@ In the previous section, we briefly learned how to obtain entity objects via seq
10
10
11
11
## Introduction
12
12
13
-
To create an entity sequence, we can use the extension function `sequenceOf`:
13
+
To use sequence APIs, we need to create sequence objects first. In general, we’d like to define some extension properties for `Database`. These properties return new created sequence objects via `sequenceOf` and they can help us improve the readability of the code:
Now we got a default sequence, which can obtain all employees from the table. Please know that Ktorm doesn't execute the query right now. The sequence provides an iterator of type `Iterator<Employee>`, only when we iterate the sequence using the iterator, the query is executed. The following code prints all employees using a for-each loop:
20
+
The function `sequenceOf` returns default sequences, by which we can obtain all entity objects from the table. Please know that Ktorm doesn't execute the queries right now. The sequence provides an iterator of type `Iterator<E>`, only when we iterate the sequence using the iterator, the query is executed. The following code prints all employees using a for-each loop:
20
21
21
22
```kotlin
22
-
for (employee insequence) {
23
+
for (employee indatabase.employees) {
23
24
println(employee)
24
25
}
25
26
```
@@ -37,13 +38,13 @@ left join t_department _ref0 on t_employee.department_id = _ref0.id
37
38
In addition to the for-each loop, we can also use the extension function `toList` to save all the items from the sequence into a list:
38
39
39
40
```kotlin
40
-
val employees =sequence.toList()
41
+
val employees =database.employees.toList()
41
42
```
42
43
43
44
We can even add a filter condition by the `filter` function before calling `toList`:
44
45
45
46
```kotlin
46
-
val employees =sequence.filter { it.departmentId eq 1 }.toList()
47
+
val employees =database.employees.filter { it.departmentId eq 1 }.toList()
47
48
```
48
49
49
50
Now the generated SQL is:
@@ -110,14 +111,13 @@ inline fun <E : Any, T : BaseTable<E>> EntitySequence<E, T>.filter(
110
111
Similar to the `filter` function of `kotlin.sequences`, the `filter` function here also accepts a closure as its parameter, and the returned value from the closure will be used as a filter condition. Differently, our closure has a parameter of type `T`, the current table object, so what we get in the closure by `it` is the table object instead of an entity element. Besides, the closure's return type is `ColumnDeclaring<Boolean>` instead of `Boolean`. The following code obtains all the employees in department 1 by using `filter`:
111
112
112
113
```kotlin
113
-
val employees = database.sequenceOf(Employees).filter { it.departmentId eq 1 }.toList()
114
+
val employees = database.employees.filter { it.departmentId eq 1 }.toList()
114
115
```
115
116
116
117
We can see that the usage is almost the same as `kotlin.sequences`, the only difference is the `==` in the lambda is replaced by the `eq` function. The `filter` function can also be called continuously, as all the filter conditions are combined with the `and` operator.
117
118
118
119
```kotlin
119
-
val employees = database
120
-
.sequenceOf(Employees)
120
+
val employees = database.employees
121
121
.filter { it.departmentId eq 1 }
122
122
.filter { it.managerId.isNotNull() }
123
123
.toList()
@@ -145,8 +145,7 @@ inline fun <E : Any, T : BaseTable<E>> EntitySequence<E, T>.filterColumns(
145
145
By default, an entity sequence selects all the columns from the current table and referenced tables (if enabled), that may lead to unnecessary performance costs. If we are sensitive to the performance issue, we can use the `filterColumns` function, which supports us to custom the selected columns in the query. Assuming we want to get a list of departments, but their location data is not required, we can write codes like:
146
146
147
147
```kotlin
148
-
val departments = database
149
-
.sequenceOf(Departments)
148
+
val departments = database.departments
150
149
.filterColumns { it.columns - it.location }
151
150
.toList()
152
151
```
@@ -169,7 +168,7 @@ inline fun <E : Any, T : BaseTable<E>> EntitySequence<E, T>.sortedBy(
169
168
Ktorm provides a `sortedBy` function, which allows us to specify the *order by* clause for the sequence's internal query. The function accepts a closure as its parameter in which we need to return a column or expression. The following code obtains all the employees and sorts them by their salaries:
170
169
171
170
```kotlin
172
-
val employees = database.sequenceOf(Employees).sortedBy { it.salary }.toList()
171
+
val employees = database.employees.sortedBy { it.salary }.toList()
173
172
```
174
173
175
174
Generated SQL:
@@ -186,8 +185,7 @@ The `sortedBy` function sorts entities in ascending order, if we need descending
186
185
Sometimes, we need to sort entities by two or more columns, then we can use the `sorted` function, which accepts a closure of type `(T) -> List<OrderByExpression>` as its parameter. The example below sorts the employees firstly by salaries descending, then by hire dates ascending:
@@ -211,7 +209,7 @@ fun <E : Any, T : BaseTable<E>> EntitySequence<E, T>.take(n: Int): EntitySequenc
211
209
The `drop` and `take` functions are designed for pagination. The `drop` function returns a new sequence containing all elements except first n elements, while the `take` function returns a new sequence only containing first n elements. Usage example:
212
210
213
211
```kotlin
214
-
val employees = database.sequenceOf(Employees).drop(1).take(1).toList()
212
+
val employees = database.employees.drop(1).take(1).toList()
215
213
```
216
214
217
215
If we are using MySQL, the generated SQL is:
@@ -238,7 +236,7 @@ fun <E : Any, C : MutableCollection<in E>> EntitySequence<E, *>.toCollection(des
238
236
The `toCollection` function is used to collect all the elements in a sequence. It'll execute the internal query right now and iterate the results, adding them to the `destination`:
239
237
240
238
```kotlin
241
-
val employees = database.sequenceOf(Employees).toCollection(ArrayList())
239
+
val employees = database.employees.toCollection(ArrayList())
242
240
```
243
241
244
242
In addition, Ktorm also provides some convenient `toXxx` functions based on `toCollection` to convert sequences to particular type of collections, they are `toList`, `toMutableList`, `toSet`, `toMutableSet`, `toHashSet`, `toSortedSet`.
@@ -257,7 +255,7 @@ The `map` function will execute the internal query and iterate the query results
257
255
The following code obtains all the employees' names:
258
256
259
257
```kotlin
260
-
val names = database.sequenceOf(Employees, withReferences =false).map { it.name }
258
+
val names = database.employees.map { it.name }
261
259
```
262
260
263
261
Generated SQL:
@@ -283,7 +281,7 @@ inline fun <E : Any, T : BaseTable<E>, C : Any> EntitySequence<E, T>.mapColumns(
283
281
The `mapColumns` function is similar to `map`. Differently, its closure accepts the current table object `T` as the parameter, so what we get in the closure by `it` is the table object instead of an entity element. Besides, the closure's return type is `ColumnDeclaring<C>`, and we should return a column or expression needed to be selected from the database. Let's implement the same example as the previous one, the following code obtains all employees' names:
284
282
285
283
```kotlin
286
-
val names = database.sequenceOf(Employees, withReferences =false).mapColumns { it.name }
284
+
val names = database.employees.mapColumns { it.name }
287
285
```
288
286
289
287
Now we can see there is only the required column in the generated SQL:
@@ -296,15 +294,7 @@ from t_employee
296
294
If we want to select two or more columns, we can change to `mapColumns2` or `mapColumns3`, then we need to wrap our selected columns by `Pair` or `Triple` in the closure, and the function's return type becomes `List<Pair<C1?, C2?>>` or `List<Triple<C1?, C2?, C3?>>`. The example below prints the IDs, names and hired days of the employees in department 1:
@@ -350,20 +340,20 @@ In addition to the basic forms, there are also many variants for these functions
350
340
This serial of functions provide features of iteration and folding, and their usages are also the same as the corresponding ones of `kotlin.sequences`. The following code calculates the total salary of all employees:
Of course, if only the total salary is needed, we don't have to write codes in that way. Because the performance is really poor, as all employees are obtained from the database. Here we just show you the usage of the `fold` function. It's better to use `sumBy`:
357
347
358
348
```kotlin
359
-
val totalSalary = database.sequenceOf(Employees).sumBy { it.salary }
349
+
val totalSalary = database.employees.sumBy { it.salary }
360
350
```
361
351
362
352
### joinTo/joinToString
363
353
364
354
These two functions provide the feature of joining the sequence elements to strings, and their usages are also the same as the corresponding ones of `kotlin.sequences`. The following code joins all the employees' names to a string:
365
355
366
356
```kotlin
367
-
val names = database.sequenceOf(Employees).joinToString(separator =":") { it.name }
357
+
val names = database.employees.joinToString(separator =":") { it.name }
0 commit comments