From d49cd910d105e970530428d29f7185447dbbf2cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Wed, 12 Jul 2023 20:32:27 +0800 Subject: [PATCH] feat: add extraConditions config for `@RelationManyToMany` and `@RelationOneToMany` annotations --- .../com/mybatisflex/annotation/Condition.java | 45 ++++++++++++++++++ .../annotation/RelationManyToMany.java | 6 +++ .../annotation/RelationOneToMany.java | 5 ++ .../core/relation/AbstractRelation.java | 36 +++++++++++++-- .../mybatisflex/core/relation/Condition.java | 46 +++++++++++++++++++ .../mybatisflex/core/relation/ManyToMany.java | 5 +- .../mybatisflex/core/relation/OneToMany.java | 23 +++++----- .../core/relation/ToManyRelation.java | 7 ++- .../core/relation/ToOneRelation.java | 6 ++- .../test/relation/onetoone/Account.java | 29 ++++++------ 10 files changed, 173 insertions(+), 35 deletions(-) create mode 100644 mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Condition.java create mode 100644 mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/Condition.java diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Condition.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Condition.java new file mode 100644 index 00000000..9ba6eb42 --- /dev/null +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Condition.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.annotation; + +import java.lang.annotation.*; + +/** + * 附件条件。 + * + * @author michael + */ +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface Condition { + + /** + * 列名 + */ + String column(); + + /** + * 逻辑值,> , >= , = , IS NULL, IS NOT NULL 等 + */ + String logic() default " = "; + + /** + * 值 + */ + String[] value() default {}; + +} diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToMany.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToMany.java index 25891205..24427249 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToMany.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToMany.java @@ -76,6 +76,11 @@ public @interface RelationManyToMany { */ String joinTargetColumn(); + /** + * 查询时,追加的额外条件 + */ + Condition[] extraConditions() default {}; + /** * 查询排序。 * @@ -90,4 +95,5 @@ public @interface RelationManyToMany { */ String dataSource() default ""; + } diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java index 53b9cc01..6fec3ec7 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java @@ -76,6 +76,11 @@ public @interface RelationOneToMany { */ String joinTargetColumn() default ""; + /** + * 查询时,追加的额外条件 + */ + Condition[] extraConditions() default {}; + /** * 查询排序。 * diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/AbstractRelation.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/AbstractRelation.java index 3d6bc4ab..5b3f2b5d 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/AbstractRelation.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/AbstractRelation.java @@ -26,10 +26,7 @@ import com.mybatisflex.core.util.FieldWrapper; import com.mybatisflex.core.util.StringUtil; import java.lang.reflect.Field; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import static com.mybatisflex.core.query.QueryMethods.column; @@ -54,10 +51,13 @@ abstract class AbstractRelation { protected String joinTargetColumn; protected String dataSource; + protected List extraConditions; public AbstractRelation(String selfField, String targetSchema, String targetTable, String targetField, String joinTable, String joinSelfColumn, String joinTargetColumn, - String dataSource, Class entityClass, Field relationField) { + String dataSource, Class entityClass, Field relationField, + List extraConditions + ) { this.selfEntityClass = entityClass; this.relationField = relationField; this.relationFieldWrapper = FieldWrapper.of(entityClass, relationField.getName()); @@ -80,6 +80,7 @@ abstract class AbstractRelation { this.targetFieldWrapper = FieldWrapper.of(targetEntityClass, targetField); this.targetTableInfo = TableInfoFactory.ofEntityClass(targetEntityClass); + this.extraConditions = extraConditions; } @@ -209,6 +210,13 @@ abstract class AbstractRelation { return values; } + public List getExtraConditions() { + return extraConditions; + } + + public void setExtraConditions(List extraConditions) { + this.extraConditions = extraConditions; + } public Class getMappingType() { return relationFieldWrapper.getMappingType(); @@ -253,6 +261,17 @@ abstract class AbstractRelation { return primaryKeyList.get(0).getProperty(); } + protected static List buildConditions(com.mybatisflex.annotation.Condition[] conditions){ + if (conditions == null || conditions.length == 0){ + return null; + } + List conditionList = new ArrayList<>(); + for (com.mybatisflex.annotation.Condition condition : conditions) { + conditionList.add(new Condition(condition)); + } + return conditionList; + } + /** * 构建查询目标对象的 QueryWrapper @@ -264,12 +283,19 @@ abstract class AbstractRelation { QueryWrapper queryWrapper = QueryWrapper.create() .select() .from(getTargetTableWithSchema()); + if (targetValues.size() > 1) { queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(targetValues)); } else { queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).eq(targetValues.iterator().next())); } + if (extraConditions != null) { + for (Condition extraCondition : extraConditions) { + queryWrapper.and(extraCondition.toQueryCondition()); + } + } + customizeQueryWrapper(queryWrapper); return queryWrapper; diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/Condition.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/Condition.java new file mode 100644 index 00000000..f46604a5 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/Condition.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.core.relation; + +import com.mybatisflex.core.query.QueryCondition; + +import static com.mybatisflex.core.query.QueryMethods.column; + +class Condition { + + private String column; + private String logic; + private String[] value; + + public Condition(com.mybatisflex.annotation.Condition annotation) { + this.column = annotation.column(); + this.logic = " " + annotation.logic().toUpperCase().trim()+" "; + this.value = annotation.value(); + } + + public QueryCondition toQueryCondition() { + return QueryCondition.create(column(column), logic, getValue()); + } + + public Object getValue() { + if (value == null || value.length == 0) { + return null; + } else if (value.length == 1) { + return value[0]; + } + return value; + } +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToMany.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToMany.java index 82bd08a8..4bcf6ebc 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToMany.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToMany.java @@ -33,14 +33,15 @@ class ManyToMany extends ToManyRelation { , annotation.joinTable() , annotation.joinSelfColumn() , annotation.joinTargetColumn() - , annotation.dataSource(), entityClass, relationField); + , annotation.dataSource(), entityClass, relationField + , buildConditions(annotation.extraConditions())); this.orderBy = annotation.orderBy(); } @Override public void customizeQueryWrapper(QueryWrapper queryWrapper) { - if (StringUtil.isNotBlank(orderBy)){ + if (StringUtil.isNotBlank(orderBy)) { queryWrapper.orderBy(orderBy); } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToMany.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToMany.java index bf8c5f95..68e9aa22 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToMany.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToMany.java @@ -23,31 +23,32 @@ import java.lang.reflect.Field; class OneToMany extends ToManyRelation { - private String orderBy; - private int limit; + private String orderBy; + private int limit; - public OneToMany(RelationOneToMany annotation, Class entityClass, Field relationField) { - super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationOneToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") + public OneToMany(RelationOneToMany annotation, Class entityClass, Field relationField) { + super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationOneToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") , annotation.targetSchema() , annotation.targetTable() - , annotation.targetField() + , annotation.targetField() , annotation.joinTable() , annotation.joinSelfColumn() , annotation.joinTargetColumn() - , annotation.dataSource(), entityClass, relationField); - this.orderBy = annotation.orderBy(); - this.limit = annotation.limit(); - } + , annotation.dataSource(), entityClass, relationField + , buildConditions(annotation.extraConditions())); + this.orderBy = annotation.orderBy(); + this.limit = annotation.limit(); + } @Override public void customizeQueryWrapper(QueryWrapper queryWrapper) { - if (StringUtil.isNotBlank(orderBy)){ + if (StringUtil.isNotBlank(orderBy)) { queryWrapper.orderBy(orderBy); } - if (limit > 0){ + if (limit > 0) { queryWrapper.limit(limit); } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java index 2bd50a95..b86b51e2 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java @@ -30,10 +30,13 @@ class ToManyRelation extends AbstractRelation { public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField, String joinTable, String joinSelfColumn, String joinTargetColumn, - String dataSource, Class selfEntityClass, Field relationField) { + String dataSource, Class selfEntityClass, Field relationField, + List extraConditions) { super(selfField, targetSchema, targetTable, targetField, joinTable, joinSelfColumn, joinTargetColumn, - dataSource, selfEntityClass, relationField); + dataSource, selfEntityClass, relationField, + extraConditions + ); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToOneRelation.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToOneRelation.java index a42c1afa..0eaaa777 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToOneRelation.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToOneRelation.java @@ -28,7 +28,9 @@ class ToOneRelation extends AbstractRelation { String dataSource, Class selfEntityClass, Field relationField) { super(selfField, targetSchema, targetTable, targetField, joinTable, joinSelfColumn, joinTargetColumn, - dataSource, selfEntityClass, relationField); + dataSource, selfEntityClass, relationField, + null + ); } @@ -65,7 +67,7 @@ class ToOneRelation extends AbstractRelation { if (selfValue.equals(String.valueOf(mappingRow.getIgnoreCase(joinSelfColumn)))) { Object joinValue = mappingRow.getIgnoreCase(joinTargetColumn); if (joinValue != null) { - return joinValue.toString(); + return joinValue.toString(); } } } diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/relation/onetoone/Account.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/relation/onetoone/Account.java index 7d72e926..d1c86261 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/relation/onetoone/Account.java +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/relation/onetoone/Account.java @@ -32,7 +32,7 @@ public class Account implements Serializable { private int age; // @RelationOneToOne(selfField = "id", targetField = "accountId") - @RelationOneToOne(targetField = "accountId") +// @RelationOneToOne(targetField = "accountId") // @RelationManyToOne(joinTable = "tb_idcard_mapping",joinSelfColumn = "account_id",joinTargetColumn = "idcard_id" // ,selfField = "id",targetField = "accountId") private IDCard idCard; @@ -46,11 +46,14 @@ public class Account implements Serializable { // selfField = "id", joinSelfColumn = "account_id", // targetField = "id", joinTargetColumn = "role_id" // ) -// @RelationManyToMany( -// joinTable = "tb_role_mapping", -// joinSelfColumn = "account_id", -// joinTargetColumn = "role_id" -// ) + @RelationManyToMany( + joinTable = "tb_role_mapping", + joinSelfColumn = "account_id", + joinTargetColumn = "role_id", + extraConditions = { + @Condition(column = "name", logic = "is not null"), + } + ) private List roles; @@ -105,12 +108,12 @@ public class Account implements Serializable { @Override public String toString() { return "Account{" + - "id=" + id + - ", userName='" + userName + '\'' + - ", age=" + age + - ", idCard=" + idCard + - ", books=" + books + - ", roles=" + roles + - '}'; + "id=" + id + + ", userName='" + userName + '\'' + + ", age=" + age + + ", idCard=" + idCard + + ", books=" + books + + ", roles=" + roles + + '}'; } }