Skip to content

Commit 1abdcec

Browse files
committed
Added max and min queries
1 parent 0b7d0c8 commit 1abdcec

File tree

14 files changed

+483
-117
lines changed

14 files changed

+483
-117
lines changed

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Include the Maven artifact:
2020
<dependency>
2121
<groupId>com.github.collinalpert</groupId>
2222
<artifactId>java2db</artifactId>
23-
<version>5.0.1</version>
23+
<version>5.1.0</version>
2424
</dependency>
2525
```
2626
Or include the [JAR](https://github.com/CollinAlpert/Java2DB/releases/latest) in your project.
@@ -110,14 +110,15 @@ The last thing you need to do is give Java2DB access to your database. Set the s
110110
### CRUD operations
111111

112112
#### Create
113-
Every service class has support for creating a single as well as multiple entities at once on the database.
113+
Every service class has support for creating a single as well as multiple entities at once on the database.
114+
When creating a single entity, the id created for it on the database will also be set in the entity.
114115
Check out the different `create` methods provided by your service class.
115116
To achieve asynchronous behavior, please read the [Asynchronous operations](#asynchronous-operations) section.
116117

117118
#### Read
118-
The `BaseService` provides a `createQuery` method which allows you to manually build a query and then execute it with the `toList`, `toStream` or `toArray` methods. You should only need this approach seldomly.\
119+
The `BaseService` provides a `createQuery` method which allows you to manually build a query and then execute it with the `toList`, `toStream`, `toArray` or `toMap` methods. You should only need this approach seldomly.\
119120
Much rather, use the `getSingle` or `getMultiple` methods. `getMultiple` returns an `EntityQuery` object with a preconfigured WHERE condition and then allows you to chain some additional query options. As of the current `EntityQuery` version, WHERE, LIMIT and ORDER BY are supported. With the ORDER BY functionality, there is also the possibility to coalesce multiple columns when ordering. Effectively, the calls `createQuery().where(predicate)` and `getMultiple(predicate)` are the same. The latter is recommended.\
120-
As previously mentioned, to execute the query and retrieve a result, use the `toList`, `toStream` or `toArray` methods.
121+
As previously mentioned, to execute the query and retrieve a result, use the `toList`, `toStream`, `toArray` or `toMap` methods.
121122

122123
#### Update
123124
Every service class has support for updating a single as well as multiple entities at once on the database.
@@ -139,6 +140,9 @@ It is also possible to achieve `LIKE` operations using the String `startsWith`,
139140
### Counting
140141
For counting functionality, the `BaseService` provides a `count` method. You can use it to either count all rows in a table, or to count all rows which match a certain condition. E.g. `personService.count()` would return the total number of people while `personService.count(person -> person.getAge() >= 50)` would return the amount of people that are of age 50 and older in your table.
141142

143+
### Max/Min
144+
To get the maximal or minimal value from a table, the ``BaseService`` provides the `max()` and `min()` methods.
145+
142146
### Projections
143147
If you would not like to fetch an entire entity from the database, when building a query, you can project to a single column by using the ```project()``` method.
144148
You then have option to choose the form in which the data should be fetched, as you would normally specify when executing a built entity query.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.collinalpert</groupId>
88
<artifactId>java2db</artifactId>
9-
<version>5.0.1</version>
9+
<version>5.1.0</version>
1010
<packaging>jar</packaging>
1111

1212
<name>Java2DB</name>

src/main/java/com/github/collinalpert/java2db/mappers/BaseMapper.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
import java.util.ArrayList;
2020
import java.util.Arrays;
2121
import java.util.Calendar;
22+
import java.util.HashMap;
2223
import java.util.List;
2324
import java.util.Locale;
2425
import java.util.Map;
2526
import java.util.Optional;
2627
import java.util.function.Consumer;
28+
import java.util.function.Function;
2729
import java.util.stream.Stream;
2830

2931
import static com.github.collinalpert.java2db.utilities.Utilities.tryAction;
@@ -109,6 +111,25 @@ public E[] mapToArray(ResultSet set, Map<String, String> aliases) throws SQLExce
109111
return module.getArray();
110112
}
111113

114+
/**
115+
* Maps a {@code ResultSet} to a {@link Map}.
116+
*
117+
* @param set The {@code ResultSet} to get the data from.
118+
* @param keyMapping The key function of the map.
119+
* @param valueMapping The value function of the map.
120+
* @param aliases A map of column aliases needed to retrieve column data from the {@code ResultSet}.
121+
* @param <K> The type of the keys in the map.
122+
* @param <V> The type of the values in the map.
123+
* @return A {@code Map} containing the {@code ResultSet}s data.
124+
* @throws SQLException In case the {@code ResultSet} can't be read.
125+
*/
126+
@Override
127+
public <K, V> Map<K, V> mapToMap(ResultSet set, Function<E, K> keyMapping, Function<E, V> valueMapping, Map<String, String> aliases) throws SQLException {
128+
var map = new HashMap<K, V>();
129+
mapInternal(set, x -> map.put(keyMapping.apply(x), valueMapping.apply(x)), aliases);
130+
return map;
131+
}
132+
112133
/**
113134
* Internal handling for executing a certain action for every entity that is generated when iterating through a {@code ResultSet}.
114135
*

src/main/java/com/github/collinalpert/java2db/mappers/Mappable.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.List;
88
import java.util.Map;
99
import java.util.Optional;
10+
import java.util.function.Function;
1011
import java.util.stream.Stream;
1112

1213
/**
@@ -29,7 +30,7 @@ public interface Mappable<T extends BaseEntity> {
2930
*
3031
* @param set The {@code ResultSet} to get the data from.
3132
* @param aliases A map of column aliases needed to retrieve column data from the {@code ResultSet}.
32-
* @return An {@code Optional} containing the {@code ResultSet}s data.
33+
* @return A {@code List} containing the {@code ResultSet}s data.
3334
* @throws SQLException In case the {@code ResultSet} can't be read.
3435
*/
3536
List<T> mapToList(ResultSet set, Map<String, String> aliases) throws SQLException;
@@ -39,7 +40,7 @@ public interface Mappable<T extends BaseEntity> {
3940
*
4041
* @param set The {@code ResultSet} to get the data from.
4142
* @param aliases A map of column aliases needed to retrieve column data from the {@code ResultSet}.
42-
* @return An {@code Optional} containing the {@code ResultSet}s data.
43+
* @return A {@code Stream} containing the {@code ResultSet}s data.
4344
* @throws SQLException In case the {@code ResultSet} can't be read.
4445
*/
4546
Stream<T> mapToStream(ResultSet set, Map<String, String> aliases) throws SQLException;
@@ -49,8 +50,22 @@ public interface Mappable<T extends BaseEntity> {
4950
*
5051
* @param set The {@code ResultSet} to get the data from.
5152
* @param aliases A map of column aliases needed to retrieve column data from the {@code ResultSet}.
52-
* @return An {@code Optional} containing the {@code ResultSet}s data.
53+
* @return An array containing the {@code ResultSet}s data.
5354
* @throws SQLException In case the {@code ResultSet} can't be read.
5455
*/
5556
T[] mapToArray(ResultSet set, Map<String, String> aliases) throws SQLException;
57+
58+
/**
59+
* Maps a {@code ResultSet} to a {@link Map}.
60+
*
61+
* @param set The {@code ResultSet} to get the data from.
62+
* @param keyMapping The key function of the map.
63+
* @param valueMapping The value function of the map.
64+
* @param aliases A map of column aliases needed to retrieve column data from the {@code ResultSet}.
65+
* @param <K> The type of the keys in the map.
66+
* @param <V> The type of the values in the map.
67+
* @return A {@code Map} containing the {@code ResultSet}s data.
68+
* @throws SQLException In case the {@code ResultSet} can't be read.
69+
*/
70+
<K, V> Map<K, V> mapToMap(ResultSet set, Function<T, K> keyMapping, Function<T, V> valueMapping, Map<String, String> aliases) throws SQLException;
5671
}

src/main/java/com/github/collinalpert/java2db/queries/EntityProjectionQuery.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import java.sql.SQLException;
1010
import java.util.ArrayList;
1111
import java.util.Collections;
12+
import java.util.HashMap;
1213
import java.util.List;
14+
import java.util.Map;
1315
import java.util.Optional;
1416
import java.util.function.BiConsumer;
1517
import java.util.function.Function;
@@ -54,6 +56,41 @@ public R[] toArray() {
5456
return resultHandling(arrayModule, ArrayModule::addElement, defaultValue, ArrayModule::getArray);
5557
}
5658

59+
/**
60+
* Executes a new query and returns the result as a {@link Map}. This method is equivalent to the call {@code Queryable#toMap(keyMapping, x -> x)}.
61+
*
62+
* @param keyMapping The field representing the keys of the map.
63+
* @return A map containing the result of the query.
64+
*/
65+
@Override
66+
public <K> Map<K, R> toMap(Function<R, K> keyMapping) {
67+
return this.toMap(keyMapping, x -> x);
68+
}
69+
70+
/**
71+
* Executes a new query and returns the result as a {@link Map}.
72+
*
73+
* @param keyMapping The field representing the keys of the map.
74+
* @param valueMapping The field representing the values of the map.
75+
* @return A map containing the result of the query.
76+
*/
77+
@Override
78+
public <K, V> Map<K, V> toMap(Function<R, K> keyMapping, Function<R, V> valueMapping) {
79+
var map = new HashMap<K, V>();
80+
try (var connection = new DBConnection();
81+
var result = connection.execute(getQuery())) {
82+
while (result.next()) {
83+
var currentValue = result.getObject(1, super.returnType);
84+
map.put(keyMapping.apply(currentValue), valueMapping.apply(currentValue));
85+
}
86+
87+
return map;
88+
} catch (SQLException e) {
89+
e.printStackTrace();
90+
return Collections.emptyMap();
91+
}
92+
}
93+
5794
/**
5895
* Performs handling on a {@code ResultSet} for different data structures.
5996
*

src/main/java/com/github/collinalpert/java2db/queries/EntityQuery.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import java.util.Arrays;
1313
import java.util.Collections;
1414
import java.util.List;
15+
import java.util.Map;
1516
import java.util.Optional;
1617
import java.util.StringJoiner;
18+
import java.util.function.Function;
1719
import java.util.stream.Stream;
1820

1921
/**
@@ -68,7 +70,7 @@ public EntityQuery<E> orWhere(SqlPredicate<E> predicate) {
6870
/**
6971
* Sets an ORDER BY clauses for the DQL statement.
7072
*
71-
* @param function The column to order by..
73+
* @param function The column to order by.
7274
* @return This {@link EntityQuery} object, now with a ORDER BY clause.
7375
*/
7476
public EntityQuery<E> orderBy(SqlFunction<E, ?> function) {
@@ -245,6 +247,34 @@ public E[] toArray() {
245247
}
246248
}
247249

250+
/**
251+
* Executes a new query and returns the result as a {@link Map}. This method is equivalent to the call {@code Queryable#toMap(keyMapping, x -> x)}.
252+
*
253+
* @param keyMapping The field representing the keys of the map.
254+
* @return A map containing the result of the query.
255+
*/
256+
@Override
257+
public <K> Map<K, E> toMap(Function<E, K> keyMapping) {
258+
return this.toMap(keyMapping, x -> x);
259+
}
260+
261+
/**
262+
* Executes a new query and returns the result as a {@link Map}.
263+
*
264+
* @param keyMapping The field representing the keys of the map.
265+
* @param valueMapping The field representing the values of the map.
266+
* @return A map containing the result of the query.
267+
*/
268+
@Override
269+
public <K, V> Map<K, V> toMap(Function<E, K> keyMapping, Function<E, V> valueMapping) {
270+
try (var connection = new DBConnection()) {
271+
return super.mapper.mapToMap(connection.execute(getQuery()), keyMapping, valueMapping, super.aliases);
272+
} catch (SQLException e) {
273+
e.printStackTrace();
274+
return Collections.emptyMap();
275+
}
276+
}
277+
248278
/**
249279
* Creates the query clauses for a DQL statement. This contains constraints like a WHERE, an ORDER BY and a LIMIT statement.
250280
*

src/main/java/com/github/collinalpert/java2db/queries/Queryable.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.github.collinalpert.java2db.queries;
22

33
import java.util.List;
4+
import java.util.Map;
5+
import java.util.function.Function;
46
import java.util.stream.Stream;
57

68
/**
@@ -9,14 +11,14 @@
911
public interface Queryable<T> extends SingleQueryable<T> {
1012

1113
/**
12-
* Executes the query and returns the result as a {@link List}
14+
* Executes the query and returns the result as a {@link List}.
1315
*
1416
* @return A list of entities representing the result rows.
1517
*/
1618
List<T> toList();
1719

1820
/**
19-
* Executes the query and returns the result as a {@link Stream}
21+
* Executes the query and returns the result as a {@link Stream}.
2022
*
2123
* @return A list of entities representing the result rows.
2224
*/
@@ -28,4 +30,24 @@ public interface Queryable<T> extends SingleQueryable<T> {
2830
* @return An array of entities representing the result rows.
2931
*/
3032
T[] toArray();
33+
34+
/**
35+
* Executes a new query and returns the result as a {@link Map}. This method is equivalent to the call {@code Queryable#toMap(keyMapping, x -> x)}.
36+
*
37+
* @param keyMapping The field representing the keys of the map.
38+
* @param <K> The type of the field representing the keys.
39+
* @return A map containing the result of the query.
40+
*/
41+
<K> Map<K, T> toMap(Function<T, K> keyMapping);
42+
43+
/**
44+
* Executes a new query and returns the result as a {@link Map}.
45+
*
46+
* @param keyMapping The field representing the keys of the map.
47+
* @param valueMapping The field representing the values of the map.
48+
* @param <K> The type of the field representing the keys.
49+
* @param <V>The type of the field representing the values.
50+
* @return A map containing the result of the query.
51+
*/
52+
<K, V> Map<K, V> toMap(Function<T, K> keyMapping, Function<T, V> valueMapping);
3153
}

src/main/java/com/github/collinalpert/java2db/queries/async/AsyncEntityQuery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public AsyncEntityQuery<E> orWhere(SqlPredicate<E> predicate) {
5050
/**
5151
* Sets an ORDER BY clauses for the DQL statement.
5252
*
53-
* @param function The column to order by..
53+
* @param function The column to order by.
5454
* @return This {@link EntityQuery} object, now with a ORDER BY clause.
5555
*/
5656
@Override

src/main/java/com/github/collinalpert/java2db/queries/async/AsyncQueryable.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import com.github.collinalpert.java2db.queries.Queryable;
44

55
import java.util.List;
6+
import java.util.Map;
67
import java.util.concurrent.CompletableFuture;
78
import java.util.function.Consumer;
9+
import java.util.function.Function;
810
import java.util.stream.Stream;
911

1012
/**
@@ -77,4 +79,59 @@ default CompletableFuture<T[]> toArrayAsync() {
7779
default CompletableFuture<Void> toArrayAsync(Consumer<? super T[]> callback) {
7880
return toArrayAsync().thenAcceptAsync(callback);
7981
}
82+
83+
/**
84+
* The asynchronous version of the {@link #toMap(Function)} method.
85+
*
86+
* @param keyMapping The field representing the keys of the map.
87+
* @param <K> The type of the keys in the map.
88+
* @return The asynchronous operation which will retrieve the data from the database.
89+
* Custom handling for the {@code CompletableFuture} can be done here.
90+
* @see #toMap(Function)
91+
*/
92+
default <K> CompletableFuture<Map<K, T>> toMapAsync(Function<T, K> keyMapping) {
93+
return CompletableFuture.supplyAsync(() -> this.toMap(keyMapping));
94+
}
95+
96+
/**
97+
* The asynchronous version of the {@link #toMap(Function)} method.
98+
*
99+
* @param keyMapping The field representing the keys of the map.
100+
* @param callback The action to be applied to the result once it is fetched from the database.
101+
* @param <K> The type of the keys in the map.
102+
* @return The asynchronous operation which will retrieve the data from the database and apply the given action to the result.
103+
* @see #toMap(Function)
104+
*/
105+
default <K> CompletableFuture<Void> toMapAsync(Function<T, K> keyMapping, Consumer<? super Map<K, T>> callback) {
106+
return toMapAsync(keyMapping).thenAcceptAsync(callback);
107+
}
108+
109+
/**
110+
* The asynchronous version of the {@link #toMap(Function, Function)} method.
111+
*
112+
* @param keyMapping The field representing the keys of the map.
113+
* @param valueMapping The field representing the values of the map.
114+
* @param <K> The type of the keys in the map.
115+
* @param <V> The type of the values in the map.
116+
* @return The asynchronous operation which will retrieve the data from the database.
117+
* Custom handling for the {@code CompletableFuture} can be done here.
118+
* @see #toMap(Function, Function)
119+
*/
120+
default <K, V> CompletableFuture<Map<K, V>> toMapAsync(Function<T, K> keyMapping, Function<T, V> valueMapping) {
121+
return CompletableFuture.supplyAsync(() -> this.toMap(keyMapping, valueMapping));
122+
}
123+
124+
/**
125+
* The asynchronous version of the {@link #toMap(Function, Function)} method.
126+
*
127+
* @param keyMapping The field representing the keys of the map.
128+
* @param valueMapping The field representing the values of the map.
129+
* @param callback The action to be applied to the result once it is fetched from the database.
130+
* @param <K> The type of the keys in the map.
131+
* @param <V> The type of the values in the map.
132+
* @return The asynchronous operation which will retrieve the data from the database and apply the given action to the result.
133+
*/
134+
default <K, V> CompletableFuture<Void> toMapAsync(Function<T, K> keyMapping, Function<T, V> valueMapping, Consumer<? super Map<K, V>> callback) {
135+
return toMapAsync(keyMapping, valueMapping).thenAcceptAsync(callback);
136+
}
80137
}

src/main/java/com/github/collinalpert/java2db/queries/async/AsyncSingleQueryable.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ public interface AsyncSingleQueryable<T> extends SingleQueryable<T> {
2020
*/
2121
default CompletableFuture<Optional<T>> firstAsync() {
2222
return CompletableFuture.supplyAsync(this::first);
23-
2423
}
2524

2625
/**

0 commit comments

Comments
 (0)