diff --git a/README.md b/README.md
index c681dc3..a591672 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ Add this dependency in your pom.xml
io.github.andersoncrocha
jpql-query-builder
- 1.2.1
+ 1.2.2
```
diff --git a/pom.xml b/pom.xml
index 04c111e..2a6f441 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.github.andersoncrocha
jpql-query-builder
- 1.2.1
+ 1.2.2
JPQL Query Builder
This is a tool that helps you create queries with Hibernate using JPQL or native SQL
diff --git a/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/QueryBuilder.java b/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/QueryBuilder.java
index 9b679a4..517c2cb 100644
--- a/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/QueryBuilder.java
+++ b/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/QueryBuilder.java
@@ -11,6 +11,7 @@
import io.github.andersoncrocha.jpqlquerybuilder.operations.WhereGroup.Where;
import io.github.andersoncrocha.jpqlquerybuilder.operations.types.JoinType;
import io.github.andersoncrocha.jpqlquerybuilder.operations.types.QueryOperator;
+import io.github.andersoncrocha.jpqlquerybuilder.operations.types.SortDirection;
import io.github.andersoncrocha.jpqlquerybuilder.utils.StringUtils;
import javax.persistence.EntityManager;
@@ -24,6 +25,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
+import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public class QueryBuilder {
@@ -43,6 +45,10 @@ public class QueryBuilder {
private QueryOperator lastOperator;
private boolean nativeQuery;
+ public QueryBuilder() {
+ this(null);
+ }
+
public QueryBuilder(EntityManager entityManager) {
this.entityManager = entityManager;
this.joinGroup = new JoinGroup();
@@ -65,7 +71,7 @@ public QueryBuilder from(Class> fromClass) {
return this.from(fromClass, alias);
}
- public QueryBuilder from(Function subQueryFunction, String alias) {
+ public QueryBuilder from(UnaryOperator subQueryFunction, String alias) {
QueryBuilder queryBuilderSubQuery = subQueryFunction.apply(new QueryBuilder(entityManager));
return this.from(queryBuilderSubQuery, alias);
}
@@ -98,30 +104,92 @@ private QueryBuilder join(String target, JoinType type) {
return this;
}
+ private QueryBuilder join(String target, String alias, String condition, JoinType type) {
+ String joinTargetWithAlias = StringUtils.isNotBlank(alias)
+ ? target.concat(" ").concat(alias)
+ : target;
+ String finalTarget = StringUtils.isNotBlank(condition)
+ ? joinTargetWithAlias.concat(" ON ").concat(condition)
+ : joinTargetWithAlias;
+ return this.join(finalTarget, type);
+ }
+
+ private QueryBuilder join(Class> target, String alias, String condition, JoinType type) {
+ return this.join(target.getSimpleName(), alias, condition, type);
+ }
+
+ public QueryBuilder join(Class> joinClass, String alias, String condition) {
+ return this.join(joinClass, alias, condition, JoinType.INNER);
+ }
+
+ public QueryBuilder join(Class> joinClass, String alias) {
+ return this.join(joinClass, alias, null);
+ }
+
public QueryBuilder join(String target, String condition) {
- return this.join(target.concat(" ON ").concat(condition), JoinType.INNER);
+ return this.join(target, null, condition, JoinType.INNER);
}
public QueryBuilder join(String target) {
return this.join(target, JoinType.INNER);
}
+ public QueryBuilder joinFetch(Class> joinClass, String alias, String condition) {
+ return this.join(joinClass, alias, condition, JoinType.INNER_FETCH);
+ }
+
+ public QueryBuilder joinFetch(Class> joinClass, String alias) {
+ return this.joinFetch(joinClass, alias, null);
+ }
+
public QueryBuilder joinFetch(String target) {
return this.join(target, JoinType.INNER_FETCH);
}
+ public QueryBuilder leftJoin(Class> joinClass, String alias, String condition) {
+ return this.join(joinClass, alias, condition, JoinType.LEFT);
+ }
+
+ public QueryBuilder leftJoin(Class> joinClass, String alias) {
+ return this.leftJoin(joinClass, alias, null);
+ }
+
public QueryBuilder leftJoin(String target) {
return this.join(target, JoinType.LEFT);
}
+ public QueryBuilder leftJoinFetch(Class> joinClass, String alias, String condition) {
+ return this.join(joinClass, alias, condition, JoinType.LEFT_FETCH);
+ }
+
+ public QueryBuilder leftJoinFetch(Class> joinClass, String alias) {
+ return this.leftJoinFetch(joinClass, alias, null);
+ }
+
public QueryBuilder leftJoinFetch(String target) {
return this.join(target, JoinType.LEFT_FETCH);
}
+ public QueryBuilder rightJoin(Class> joinClass, String alias, String condition) {
+ return this.join(joinClass, alias, condition, JoinType.RIGHT);
+ }
+
+ public QueryBuilder rightJoin(Class> joinClass, String alias) {
+ return this.rightJoin(joinClass, alias, null);
+ }
+
public QueryBuilder rightJoin(String target) {
return this.join(target, JoinType.RIGHT);
}
+ public QueryBuilder rightJoinFetch(Class> joinClass, String alias, String condition) {
+ return this.join(joinClass, alias, condition, JoinType.RIGHT_FETCH);
+ }
+
+ public QueryBuilder rightJoinFetch(Class> joinClass, String alias) {
+ return this.rightJoinFetch(joinClass, alias, null);
+ }
+
public QueryBuilder rightJoinFetch(String target) {
return this.join(target, JoinType.RIGHT_FETCH);
}
@@ -149,6 +217,10 @@ public QueryBuilder whereIf(String clause, Object parameter, boolean shouldAddWh
return shouldAddWhere ? this.where(clause, parameter) : this;
}
+ public QueryBuilder whereNotIf(String clause, Object parameter, boolean shouldAddWhere) {
+ return this.whereIf(clause, parameter, !shouldAddWhere);
+ }
+
public QueryBuilder where(String clause) {
return this.where(clause, (Object) null);
}
@@ -157,6 +229,10 @@ public QueryBuilder whereIf(String clause, boolean shouldAddWhere) {
return shouldAddWhere ? this.where(clause) : this;
}
+ public QueryBuilder whereNotIf(String clause, boolean shouldAddWhere) {
+ return this.whereIf(clause, !shouldAddWhere);
+ }
+
public QueryBuilder or() {
this.lastOperator = QueryOperator.OR;
return this;
@@ -184,17 +260,21 @@ public QueryBuilder orderBy(String orderBy) {
return this;
}
- public QueryBuilder addOrderBy(String orderBy) {
- this.orderBy.addOrderBy(orderBy);
+ public QueryBuilder orderBy(String orderBy, SortDirection sortDirection) {
+ if (Objects.nonNull(this.orderBy)) {
+ this.orderBy.addOrderBy(orderBy, sortDirection);
+ } else {
+ this.orderBy = new OrderBy(orderBy, sortDirection);
+ }
return this;
}
- public QueryBuilder firstResult(Integer firstResult) {
+ public QueryBuilder firstResult(int firstResult) {
this.firstResult = firstResult;
return this;
}
- public QueryBuilder maxResults(Integer maxResults) {
+ public QueryBuilder maxResults(int maxResults) {
this.maxResults = maxResults;
return this;
}
@@ -236,6 +316,8 @@ public String getQueryString() {
}
public TypedQuery getQuery(Class resultClass) {
+ Objects.requireNonNull(entityManager, "It is not allowed to execute a query without inject a entity manager");
+
String queryString = this.getQueryString();
TypedQuery query = this.entityManager.createQuery(queryString, resultClass)
.setFirstResult(firstResult)
@@ -245,6 +327,8 @@ public TypedQuery getQuery(Class resultClass) {
}
public Query getNativeQuery() {
+ Objects.requireNonNull(entityManager, "It is not allowed to execute a query without inject a entity manager");
+
String queryString = this.getQueryString();
Query query = this.entityManager.createNativeQuery(queryString, Tuple.class)
.setFirstResult(firstResult)
diff --git a/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/operations/OrderBy.java b/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/operations/OrderBy.java
index 1ffdba0..3058937 100644
--- a/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/operations/OrderBy.java
+++ b/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/operations/OrderBy.java
@@ -1,35 +1,52 @@
package io.github.andersoncrocha.jpqlquerybuilder.operations;
-import java.util.Objects;
-import java.util.Set;
+import io.github.andersoncrocha.jpqlquerybuilder.operations.types.SortDirection;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OrderBy implements QueryOperation {
- private final Set fields;
+ private final Map fields;
public OrderBy(String fields) {
this.fields = this.prepareFields(fields);
}
+ public OrderBy(String field, SortDirection sortDirection) {
+ this.fields = new HashMap<>();
+ this.fields.put(field, sortDirection);
+ }
+
public void addOrderBy(String fields) {
- Objects.requireNonNull(fields, "addOrderBy() cannot be called before orderBy() method");
- Set preparedFields = this.prepareFields(fields);
- this.fields.addAll(preparedFields);
+ Map preparedFields = this.prepareFields(fields);
+ this.fields.putAll(preparedFields);
+ }
+
+ public void addOrderBy(String field, SortDirection sortDirection) {
+ this.fields.put(field, sortDirection);
}
@Override
public String getOperation() {
- String joinedFields = String.join(", ", this.fields);
+ String joinedFields = this.fields.entrySet()
+ .stream()
+ .map(entry -> {
+ String field = entry.getKey();
+ SortDirection sortDirection = entry.getValue();
+ return String.format("%s %s", field, sortDirection.name());
+ }).collect(Collectors.joining(", "));
return String.format("ORDER BY %s ", joinedFields);
}
- private Set prepareFields(String fields) {
+ private Map prepareFields(String fields) {
String[] separatedFields = fields.split(",");
return Stream.of(separatedFields)
.map(String::trim)
- .collect(Collectors.toSet());
+ .collect(Collectors.toMap(Function.identity(), field -> SortDirection.ASC));
}
}
diff --git a/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/operations/types/SortDirection.java b/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/operations/types/SortDirection.java
new file mode 100644
index 0000000..454bac2
--- /dev/null
+++ b/src/main/java/io/github/andersoncrocha/jpqlquerybuilder/operations/types/SortDirection.java
@@ -0,0 +1,12 @@
+package io.github.andersoncrocha.jpqlquerybuilder.operations.types;
+
+public enum SortDirection {
+
+ ASC,
+ DESC;
+
+ public static SortDirection isAscending(boolean isAscending) {
+ return isAscending ? ASC : DESC;
+ }
+
+}