diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java index 7054a97..a90733a 100644 --- a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqFilter.java @@ -31,7 +31,9 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.function.Consumer; +import java.util.stream.Collectors; import static dev.struchkov.haiti.filter.jooq.exception.FilterJooqHaitiException.filterJooqException; import static java.util.stream.Collectors.toList; @@ -207,24 +209,34 @@ public class CriteriaJooqFilter { if (!joinTables.isEmpty()) { for (JoinTable joinTable : joinTables) { final String tableName = joinTable.getTableName(); - String fieldBase = joinTable.getFieldBase(); - String fieldReference = joinTable.getFieldReference(); Table dlsJoinTableName = DSL.table(tableName); - if (joinTable.getAlias() != null) { dlsJoinTableName = dlsJoinTableName.as(joinTable.getAlias()); - fieldReference = joinTable.getAlias() + "." + fieldReference; - } else { - fieldReference = tableName + "." + fieldReference; } + final Set joinConditions = joinTable.getFieldReferences().stream() + .map(reference -> { + String fieldBase = reference.getBaseField(); + String fieldReference = reference.getReferenceField(); + + if (joinTable.getAlias() != null) { + fieldReference = joinTable.getAlias() + "." + fieldReference; + } else { + fieldReference = tableName + "." + fieldReference; + } + + final Field dslFieldBase = field(fieldBase); + final Field dslFieldReference = field(fieldReference); + + return dslFieldBase.eq(dslFieldReference); + + }) + .collect(Collectors.toSet()); + final JoinTypeOperation joinType = joinTable.getJoinTypeOperation(); - final Field dslFieldBase = field(fieldBase); - final Field dslFieldReference = field(fieldReference); - - final Condition on = dslFieldBase.eq(dslFieldReference); + final Condition on = DSL.and(joinConditions); switch (joinType) { case LEFT: from = from.leftJoin(dlsJoinTableName).on(on); diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java index f5c092a..ef462f2 100644 --- a/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/CriteriaJooqQuery.java @@ -136,6 +136,16 @@ public class CriteriaJooqQuery { return this; } + public CriteriaJooqQuery isNull(String field) { + conditions.add(DSL.field(field).isNull()); + return this; + } + + public CriteriaJooqQuery isNotNull(String field) { + conditions.add(DSL.field(field).isNotNull()); + return this; + } + public CriteriaJooqQuery like(String field, String value, boolean ignoreCase) { Inspector.isNotNull(field); final Field query = field(field); diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinFieldReference.java b/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinFieldReference.java new file mode 100644 index 0000000..7f1afb8 --- /dev/null +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinFieldReference.java @@ -0,0 +1,31 @@ +package dev.struchkov.haiti.filter.jooq.join; + +import java.util.Set; + +public class JoinFieldReference { + + private final String baseField; + private final String referenceField; + + public JoinFieldReference(String baseField, String referenceField) { + this.baseField = baseField; + this.referenceField = referenceField; + } + + public String getBaseField() { + return baseField; + } + + public String getReferenceField() { + return referenceField; + } + + public static JoinFieldReference of(String baseField, String referenceField) { + return new JoinFieldReference(baseField, referenceField); + } + + public static Set ofSingletonSet(String baseField, String referenceField) { + return Set.of(new JoinFieldReference(baseField, referenceField)); + } + +} \ No newline at end of file diff --git a/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinTable.java b/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinTable.java index 3f4174e..b6cced5 100644 --- a/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinTable.java +++ b/src/main/java/dev/struchkov/haiti/filter/jooq/join/JoinTable.java @@ -2,6 +2,10 @@ package dev.struchkov.haiti.filter.jooq.join; import dev.struchkov.haiti.utils.Inspector; +import java.util.Set; + +import static dev.struchkov.haiti.filter.jooq.exception.FilterJooqHaitiException.filterJooqException; + /** * Контейнер для соединения с таблицами. * @@ -10,59 +14,87 @@ import dev.struchkov.haiti.utils.Inspector; public class JoinTable { private final String tableName; - private final String fieldBase; - private final String fieldReference; + private final Set fieldReferences; private final JoinTypeOperation joinTypeOperation; private String alias; - private JoinTable(String tableName, String fieldBase, String fieldReference, JoinTypeOperation joinTypeOperation, String alias) { + private JoinTable(String tableName, JoinTypeOperation joinTypeOperation, Set fieldReferences, String alias) { this.tableName = tableName; - this.fieldBase = fieldBase; - this.fieldReference = fieldReference; this.joinTypeOperation = joinTypeOperation; + this.fieldReferences = fieldReferences; this.alias = alias; } public static JoinTable ofLeft(String tableName, String fieldBase, String fieldReference) { Inspector.isNotNull(tableName, fieldBase, fieldReference); - return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.LEFT, null); + return new JoinTable(tableName, JoinTypeOperation.LEFT, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), null); + } + + public static JoinTable ofLeft(String tableName, Set fieldReferences) { + Inspector.isNotNull(tableName, fieldReferences); + Inspector.isNotEmpty(fieldReferences, filterJooqException("fieldReferences is empty: {0}", fieldReferences)); + return new JoinTable(tableName, JoinTypeOperation.LEFT, fieldReferences, null); } public static JoinTable ofLeft(String tableName, String fieldBase, String fieldReference, String alias) { Inspector.isNotNull(tableName, fieldBase, fieldReference, alias); - return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.LEFT, alias); + return new JoinTable(tableName, JoinTypeOperation.LEFT, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), alias); + } + + public static JoinTable ofLeft(String tableName, Set fieldReferences, String alias) { + Inspector.isNotNull(tableName, fieldReferences, alias); + Inspector.isNotEmpty(fieldReferences, filterJooqException("fieldReferences is empty: {0}", fieldReferences)); + return new JoinTable(tableName, JoinTypeOperation.LEFT, fieldReferences, alias); } public static JoinTable onRight(String tableName, String fieldBase, String fieldReference) { Inspector.isNotNull(tableName, fieldBase, fieldReference); - return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.RIGHT, null); + return new JoinTable(tableName, JoinTypeOperation.RIGHT, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), null); + } + + public static JoinTable onRight(String tableName, Set fieldReferences) { + Inspector.isNotNull(tableName, fieldReferences); + Inspector.isNotEmpty(fieldReferences, filterJooqException("fieldReferences is empty: {0}", fieldReferences)); + return new JoinTable(tableName, JoinTypeOperation.RIGHT, fieldReferences, null); } public static JoinTable onRight(String tableName, String fieldBase, String fieldReference, String alias) { Inspector.isNotNull(tableName, fieldBase, fieldReference, alias); - return new JoinTable(tableName, fieldBase, fieldReference, JoinTypeOperation.RIGHT, alias); + return new JoinTable(tableName, JoinTypeOperation.RIGHT, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), alias); + } + + public static JoinTable onRight(String tableName, Set fieldReferences, String alias) { + Inspector.isNotNull(tableName, fieldReferences, alias); + Inspector.isFalse(fieldReferences.isEmpty(), filterJooqException("fieldReferences is empty: {0}", fieldReferences)); + return new JoinTable(tableName, JoinTypeOperation.RIGHT, fieldReferences, alias); } public static JoinTable of(String tableName, String fieldBase, String fieldReference, JoinTypeOperation joinType) { Inspector.isNotNull(tableName, fieldBase, fieldReference); - return new JoinTable(tableName, fieldBase, fieldReference, joinType, null); + return new JoinTable(tableName, joinType, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), null); + } + + public static JoinTable of(String tableName, Set fieldReferences, JoinTypeOperation joinType) { + Inspector.isNotNull(tableName, fieldReferences); + return new JoinTable(tableName, joinType, fieldReferences, null); } public static JoinTable of(String tableName, String fieldBase, String fieldReference, JoinTypeOperation joinType, String alias) { Inspector.isNotNull(tableName, fieldBase, fieldReference, alias); - return new JoinTable(tableName, fieldBase, fieldReference, joinType, alias); + return new JoinTable(tableName, joinType, JoinFieldReference.ofSingletonSet(fieldBase, fieldReference), alias); + } + + public static JoinTable of(String tableName, Set fieldReferences, JoinTypeOperation joinType, String alias) { + Inspector.isNotNull(tableName, fieldReferences, alias); + return new JoinTable(tableName, joinType, fieldReferences, alias); } public String getTableName() { return tableName; } - public String getFieldBase() { - return fieldBase; - } - - public String getFieldReference() { - return fieldReference; + public Set getFieldReferences() { + return fieldReferences; } public JoinTypeOperation getJoinTypeOperation() {