feat: add extraConditions config for @RelationManyToMany and @RelationOneToMany annotations

This commit is contained in:
开源海哥 2023-07-12 20:32:27 +08:00
parent ba0ce49d50
commit d49cd910d1
10 changed files with 173 additions and 35 deletions

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 {};
}

View File

@ -76,6 +76,11 @@ public @interface RelationManyToMany {
*/ */
String joinTargetColumn(); String joinTargetColumn();
/**
* 查询时追加的额外条件
*/
Condition[] extraConditions() default {};
/** /**
* 查询排序 * 查询排序
* *
@ -90,4 +95,5 @@ public @interface RelationManyToMany {
*/ */
String dataSource() default ""; String dataSource() default "";
} }

View File

@ -76,6 +76,11 @@ public @interface RelationOneToMany {
*/ */
String joinTargetColumn() default ""; String joinTargetColumn() default "";
/**
* 查询时追加的额外条件
*/
Condition[] extraConditions() default {};
/** /**
* 查询排序 * 查询排序
* *

View File

@ -26,10 +26,7 @@ import com.mybatisflex.core.util.FieldWrapper;
import com.mybatisflex.core.util.StringUtil; import com.mybatisflex.core.util.StringUtil;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Collections; import java.util.*;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import static com.mybatisflex.core.query.QueryMethods.column; import static com.mybatisflex.core.query.QueryMethods.column;
@ -54,10 +51,13 @@ abstract class AbstractRelation<SelfEntity> {
protected String joinTargetColumn; protected String joinTargetColumn;
protected String dataSource; protected String dataSource;
protected List<Condition> extraConditions;
public AbstractRelation(String selfField, String targetSchema, String targetTable, String targetField, public AbstractRelation(String selfField, String targetSchema, String targetTable, String targetField,
String joinTable, String joinSelfColumn, String joinTargetColumn, String joinTable, String joinSelfColumn, String joinTargetColumn,
String dataSource, Class<SelfEntity> entityClass, Field relationField) { String dataSource, Class<SelfEntity> entityClass, Field relationField,
List<Condition> extraConditions
) {
this.selfEntityClass = entityClass; this.selfEntityClass = entityClass;
this.relationField = relationField; this.relationField = relationField;
this.relationFieldWrapper = FieldWrapper.of(entityClass, relationField.getName()); this.relationFieldWrapper = FieldWrapper.of(entityClass, relationField.getName());
@ -80,6 +80,7 @@ abstract class AbstractRelation<SelfEntity> {
this.targetFieldWrapper = FieldWrapper.of(targetEntityClass, targetField); this.targetFieldWrapper = FieldWrapper.of(targetEntityClass, targetField);
this.targetTableInfo = TableInfoFactory.ofEntityClass(targetEntityClass); this.targetTableInfo = TableInfoFactory.ofEntityClass(targetEntityClass);
this.extraConditions = extraConditions;
} }
@ -209,6 +210,13 @@ abstract class AbstractRelation<SelfEntity> {
return values; return values;
} }
public List<Condition> getExtraConditions() {
return extraConditions;
}
public void setExtraConditions(List<Condition> extraConditions) {
this.extraConditions = extraConditions;
}
public Class<?> getMappingType() { public Class<?> getMappingType() {
return relationFieldWrapper.getMappingType(); return relationFieldWrapper.getMappingType();
@ -253,6 +261,17 @@ abstract class AbstractRelation<SelfEntity> {
return primaryKeyList.get(0).getProperty(); return primaryKeyList.get(0).getProperty();
} }
protected static List<Condition> buildConditions(com.mybatisflex.annotation.Condition[] conditions){
if (conditions == null || conditions.length == 0){
return null;
}
List<Condition> conditionList = new ArrayList<>();
for (com.mybatisflex.annotation.Condition condition : conditions) {
conditionList.add(new Condition(condition));
}
return conditionList;
}
/** /**
* 构建查询目标对象的 QueryWrapper * 构建查询目标对象的 QueryWrapper
@ -264,12 +283,19 @@ abstract class AbstractRelation<SelfEntity> {
QueryWrapper queryWrapper = QueryWrapper.create() QueryWrapper queryWrapper = QueryWrapper.create()
.select() .select()
.from(getTargetTableWithSchema()); .from(getTargetTableWithSchema());
if (targetValues.size() > 1) { if (targetValues.size() > 1) {
queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(targetValues)); queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(targetValues));
} else { } else {
queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).eq(targetValues.iterator().next())); queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).eq(targetValues.iterator().next()));
} }
if (extraConditions != null) {
for (Condition extraCondition : extraConditions) {
queryWrapper.and(extraCondition.toQueryCondition());
}
}
customizeQueryWrapper(queryWrapper); customizeQueryWrapper(queryWrapper);
return queryWrapper; return queryWrapper;

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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;
}
}

View File

@ -33,14 +33,15 @@ class ManyToMany<SelfEntity> extends ToManyRelation<SelfEntity> {
, annotation.joinTable() , annotation.joinTable()
, annotation.joinSelfColumn() , annotation.joinSelfColumn()
, annotation.joinTargetColumn() , annotation.joinTargetColumn()
, annotation.dataSource(), entityClass, relationField); , annotation.dataSource(), entityClass, relationField
, buildConditions(annotation.extraConditions()));
this.orderBy = annotation.orderBy(); this.orderBy = annotation.orderBy();
} }
@Override @Override
public void customizeQueryWrapper(QueryWrapper queryWrapper) { public void customizeQueryWrapper(QueryWrapper queryWrapper) {
if (StringUtil.isNotBlank(orderBy)){ if (StringUtil.isNotBlank(orderBy)) {
queryWrapper.orderBy(orderBy); queryWrapper.orderBy(orderBy);
} }
} }

View File

@ -23,31 +23,32 @@ import java.lang.reflect.Field;
class OneToMany<SelfEntity> extends ToManyRelation<SelfEntity> { class OneToMany<SelfEntity> extends ToManyRelation<SelfEntity> {
private String orderBy; private String orderBy;
private int limit; private int limit;
public OneToMany(RelationOneToMany annotation, Class<SelfEntity> entityClass, Field relationField) { public OneToMany(RelationOneToMany annotation, Class<SelfEntity> entityClass, Field relationField) {
super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationOneToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationOneToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"")
, annotation.targetSchema() , annotation.targetSchema()
, annotation.targetTable() , annotation.targetTable()
, annotation.targetField() , annotation.targetField()
, annotation.joinTable() , annotation.joinTable()
, annotation.joinSelfColumn() , annotation.joinSelfColumn()
, annotation.joinTargetColumn() , annotation.joinTargetColumn()
, annotation.dataSource(), entityClass, relationField); , annotation.dataSource(), entityClass, relationField
this.orderBy = annotation.orderBy(); , buildConditions(annotation.extraConditions()));
this.limit = annotation.limit(); this.orderBy = annotation.orderBy();
} this.limit = annotation.limit();
}
@Override @Override
public void customizeQueryWrapper(QueryWrapper queryWrapper) { public void customizeQueryWrapper(QueryWrapper queryWrapper) {
if (StringUtil.isNotBlank(orderBy)){ if (StringUtil.isNotBlank(orderBy)) {
queryWrapper.orderBy(orderBy); queryWrapper.orderBy(orderBy);
} }
if (limit > 0){ if (limit > 0) {
queryWrapper.limit(limit); queryWrapper.limit(limit);
} }
} }

View File

@ -30,10 +30,13 @@ class ToManyRelation<SelfEntity> extends AbstractRelation<SelfEntity> {
public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField, public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField,
String joinTable, String joinSelfColumn, String joinTargetColumn, String joinTable, String joinSelfColumn, String joinTargetColumn,
String dataSource, Class<SelfEntity> selfEntityClass, Field relationField) { String dataSource, Class<SelfEntity> selfEntityClass, Field relationField,
List<Condition> extraConditions) {
super(selfField, targetSchema, targetTable, targetField, super(selfField, targetSchema, targetTable, targetField,
joinTable, joinSelfColumn, joinTargetColumn, joinTable, joinSelfColumn, joinTargetColumn,
dataSource, selfEntityClass, relationField); dataSource, selfEntityClass, relationField,
extraConditions
);
} }

View File

@ -28,7 +28,9 @@ class ToOneRelation<SelfEntity> extends AbstractRelation<SelfEntity> {
String dataSource, Class<SelfEntity> selfEntityClass, Field relationField) { String dataSource, Class<SelfEntity> selfEntityClass, Field relationField) {
super(selfField, targetSchema, targetTable, targetField, super(selfField, targetSchema, targetTable, targetField,
joinTable, joinSelfColumn, joinTargetColumn, joinTable, joinSelfColumn, joinTargetColumn,
dataSource, selfEntityClass, relationField); dataSource, selfEntityClass, relationField,
null
);
} }
@ -65,7 +67,7 @@ class ToOneRelation<SelfEntity> extends AbstractRelation<SelfEntity> {
if (selfValue.equals(String.valueOf(mappingRow.getIgnoreCase(joinSelfColumn)))) { if (selfValue.equals(String.valueOf(mappingRow.getIgnoreCase(joinSelfColumn)))) {
Object joinValue = mappingRow.getIgnoreCase(joinTargetColumn); Object joinValue = mappingRow.getIgnoreCase(joinTargetColumn);
if (joinValue != null) { if (joinValue != null) {
return joinValue.toString(); return joinValue.toString();
} }
} }
} }

View File

@ -32,7 +32,7 @@ public class Account implements Serializable {
private int age; private int age;
// @RelationOneToOne(selfField = "id", targetField = "accountId") // @RelationOneToOne(selfField = "id", targetField = "accountId")
@RelationOneToOne(targetField = "accountId") // @RelationOneToOne(targetField = "accountId")
// @RelationManyToOne(joinTable = "tb_idcard_mapping",joinSelfColumn = "account_id",joinTargetColumn = "idcard_id" // @RelationManyToOne(joinTable = "tb_idcard_mapping",joinSelfColumn = "account_id",joinTargetColumn = "idcard_id"
// ,selfField = "id",targetField = "accountId") // ,selfField = "id",targetField = "accountId")
private IDCard idCard; private IDCard idCard;
@ -46,11 +46,14 @@ public class Account implements Serializable {
// selfField = "id", joinSelfColumn = "account_id", // selfField = "id", joinSelfColumn = "account_id",
// targetField = "id", joinTargetColumn = "role_id" // targetField = "id", joinTargetColumn = "role_id"
// ) // )
// @RelationManyToMany( @RelationManyToMany(
// joinTable = "tb_role_mapping", joinTable = "tb_role_mapping",
// joinSelfColumn = "account_id", joinSelfColumn = "account_id",
// joinTargetColumn = "role_id" joinTargetColumn = "role_id",
// ) extraConditions = {
@Condition(column = "name", logic = "is not null"),
}
)
private List<Role> roles; private List<Role> roles;
@ -105,12 +108,12 @@ public class Account implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "Account{" + return "Account{" +
"id=" + id + "id=" + id +
", userName='" + userName + '\'' + ", userName='" + userName + '\'' +
", age=" + age + ", age=" + age +
", idCard=" + idCard + ", idCard=" + idCard +
", books=" + books + ", books=" + books +
", roles=" + roles + ", roles=" + roles +
'}'; '}';
} }
} }