mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 00:58:24 +08:00
refactor: optimize extraCondition
This commit is contained in:
parent
04ba382c5c
commit
c13bf3b108
@ -1,45 +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 {};
|
||||
|
||||
}
|
||||
///*
|
||||
// * 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 {};
|
||||
//
|
||||
//}
|
||||
|
||||
@ -91,7 +91,7 @@ public @interface RelationManyToMany {
|
||||
/**
|
||||
* 查询时,追加的额外条件。
|
||||
*/
|
||||
Condition[] extraConditions() default {};
|
||||
String extraCondition() default "";
|
||||
|
||||
/**
|
||||
* 查询排序。
|
||||
|
||||
@ -91,7 +91,7 @@ public @interface RelationOneToMany {
|
||||
/**
|
||||
* 查询时,追加的额外条件。
|
||||
*/
|
||||
Condition[] extraConditions() default {};
|
||||
String extraCondition() default "";
|
||||
|
||||
/**
|
||||
* 查询排序。
|
||||
|
||||
@ -32,6 +32,7 @@ import static com.mybatisflex.core.query.QueryMethods.column;
|
||||
|
||||
abstract class AbstractRelation<SelfEntity> {
|
||||
|
||||
protected String name;
|
||||
protected Class<SelfEntity> selfEntityClass;
|
||||
protected Field relationField;
|
||||
protected FieldWrapper relationFieldWrapper;
|
||||
@ -51,13 +52,16 @@ abstract class AbstractRelation<SelfEntity> {
|
||||
protected String joinTargetColumn;
|
||||
|
||||
protected String dataSource;
|
||||
protected List<Condition> extraConditions;
|
||||
|
||||
protected String extraConditionSql;
|
||||
protected List<String> extraConditionParamKeys;
|
||||
|
||||
public AbstractRelation(String selfField, String targetSchema, String targetTable, String targetField,
|
||||
String joinTable, String joinSelfColumn, String joinTargetColumn,
|
||||
String dataSource, Class<SelfEntity> entityClass, Field relationField,
|
||||
List<Condition> extraConditions
|
||||
String extraCondition
|
||||
) {
|
||||
this.name = entityClass.getSimpleName()+"."+relationField.getName();
|
||||
this.selfEntityClass = entityClass;
|
||||
this.relationField = relationField;
|
||||
this.relationFieldWrapper = FieldWrapper.of(entityClass, relationField.getName());
|
||||
@ -80,9 +84,64 @@ abstract class AbstractRelation<SelfEntity> {
|
||||
this.targetFieldWrapper = FieldWrapper.of(targetEntityClass, targetField);
|
||||
|
||||
this.targetTableInfo = TableInfoFactory.ofEntityClass(targetEntityClass);
|
||||
this.extraConditions = extraConditions;
|
||||
|
||||
initExtraCondition(extraCondition);
|
||||
}
|
||||
|
||||
protected void initExtraCondition(String extraCondition) {
|
||||
if (StringUtil.isBlank(extraCondition)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
List<String> sqlParamKeys = null;
|
||||
char[] chars = extraCondition.toCharArray();
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
sqlBuilder.append(chars[0]);
|
||||
char prev, current;
|
||||
boolean keyStart = false;
|
||||
StringBuilder currentKey = null;
|
||||
for (int i = 1; i < chars.length; i++) {
|
||||
prev = chars[i - 1];
|
||||
current = chars[i];
|
||||
if (prev == ' ' && current == ':') {
|
||||
keyStart = true;
|
||||
currentKey = new StringBuilder();
|
||||
} else if (keyStart) {
|
||||
if (current != ' ' && current != ')') {
|
||||
currentKey.append(current);
|
||||
} else {
|
||||
if (sqlParamKeys == null) {
|
||||
sqlParamKeys = new ArrayList<>();
|
||||
}
|
||||
sqlParamKeys.add(currentKey.toString());
|
||||
sqlBuilder.append("?").append(current);
|
||||
keyStart = false;
|
||||
currentKey = null;
|
||||
}
|
||||
} else {
|
||||
sqlBuilder.append(current);
|
||||
}
|
||||
}
|
||||
if (keyStart && currentKey != null && currentKey.length() > 0) {
|
||||
if (sqlParamKeys == null) {
|
||||
sqlParamKeys = new ArrayList<>();
|
||||
}
|
||||
sqlParamKeys.add(currentKey.toString());
|
||||
sqlBuilder.append(" ?");
|
||||
}
|
||||
|
||||
this.extraConditionSql = sqlBuilder.toString();
|
||||
this.extraConditionParamKeys = sqlParamKeys != null ? sqlParamKeys : Collections.emptyList();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Class<SelfEntity> getSelfEntityClass() {
|
||||
return selfEntityClass;
|
||||
@ -210,13 +269,6 @@ abstract class AbstractRelation<SelfEntity> {
|
||||
return values;
|
||||
}
|
||||
|
||||
public List<Condition> getExtraConditions() {
|
||||
return extraConditions;
|
||||
}
|
||||
|
||||
public void setExtraConditions(List<Condition> extraConditions) {
|
||||
this.extraConditions = extraConditions;
|
||||
}
|
||||
|
||||
public Class<?> getMappingType() {
|
||||
return relationFieldWrapper.getMappingType();
|
||||
@ -261,17 +313,6 @@ abstract class AbstractRelation<SelfEntity> {
|
||||
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
|
||||
@ -290,10 +331,8 @@ abstract class AbstractRelation<SelfEntity> {
|
||||
queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).eq(targetValues.iterator().next()));
|
||||
}
|
||||
|
||||
if (extraConditions != null) {
|
||||
for (Condition extraCondition : extraConditions) {
|
||||
queryWrapper.and(extraCondition.toQueryCondition());
|
||||
}
|
||||
if (StringUtil.isNotBlank(extraConditionSql)) {
|
||||
queryWrapper.and(extraConditionSql, RelationManager.getExtraConditionParams(extraConditionParamKeys));
|
||||
}
|
||||
|
||||
customizeQueryWrapper(queryWrapper);
|
||||
|
||||
@ -1,46 +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;
|
||||
}
|
||||
}
|
||||
///*
|
||||
// * 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;
|
||||
// }
|
||||
//}
|
||||
|
||||
@ -34,7 +34,7 @@ class ManyToMany<SelfEntity> extends ToManyRelation<SelfEntity> {
|
||||
, annotation.joinSelfColumn()
|
||||
, annotation.joinTargetColumn()
|
||||
, annotation.dataSource(), entityClass, relationField
|
||||
, buildConditions(annotation.extraConditions()));
|
||||
, annotation.extraCondition());
|
||||
this.orderBy = annotation.orderBy();
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ class OneToMany<SelfEntity> extends ToManyRelation<SelfEntity> {
|
||||
, annotation.joinSelfColumn()
|
||||
, annotation.joinTargetColumn()
|
||||
, annotation.dataSource(), entityClass, relationField
|
||||
, buildConditions(annotation.extraConditions()));
|
||||
, annotation.extraCondition());
|
||||
this.orderBy = annotation.orderBy();
|
||||
this.limit = annotation.limit();
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import com.mybatisflex.annotation.RelationManyToOne;
|
||||
import com.mybatisflex.annotation.RelationOneToMany;
|
||||
import com.mybatisflex.annotation.RelationOneToOne;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import com.mybatisflex.core.FlexConsts;
|
||||
import com.mybatisflex.core.datasource.DataSourceKey;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.row.Row;
|
||||
@ -43,7 +44,17 @@ public class RelationManager {
|
||||
}
|
||||
|
||||
private static Map<Class<?>, List<AbstractRelation>> classRelations = new ConcurrentHashMap<>();
|
||||
private static ThreadLocal<Integer> depthThreadLocal = ThreadLocal.withInitial(() -> 3);
|
||||
|
||||
/**
|
||||
* 递归查询深度,默认为 2,在一些特殊场景下可以修改这个值
|
||||
*/
|
||||
private static ThreadLocal<Integer> depthThreadLocal = ThreadLocal.withInitial(() -> 2);
|
||||
|
||||
/**
|
||||
* 附加条件的查询参数
|
||||
*/
|
||||
private static ThreadLocal<Map<String, Object>> extraConditionParams = new ThreadLocal<>();
|
||||
|
||||
|
||||
private static List<AbstractRelation> getRelations(Class<?> clazz) {
|
||||
return MapUtil.computeIfAbsent(classRelations, clazz, RelationManager::doGetRelations);
|
||||
@ -76,14 +87,49 @@ public class RelationManager {
|
||||
return relations;
|
||||
}
|
||||
|
||||
public static void setMaxDepth(int maxDepth){
|
||||
public static void setMaxDepth(int maxDepth) {
|
||||
depthThreadLocal.set(maxDepth);
|
||||
}
|
||||
|
||||
public static int getMaxDepth(){
|
||||
public static int getMaxDepth() {
|
||||
return depthThreadLocal.get();
|
||||
}
|
||||
|
||||
public static void setExtraConditionParams(Map<String, Object> params) {
|
||||
extraConditionParams.set(params);
|
||||
}
|
||||
|
||||
public static void addExtraConditionParam(String key, String value) {
|
||||
Map<String, Object> params = extraConditionParams.get();
|
||||
if (params == null) {
|
||||
params = new HashMap<>();
|
||||
extraConditionParams.set(params);
|
||||
}
|
||||
params.put(key, value);
|
||||
}
|
||||
|
||||
public static Map<String, Object> getExtraConditionParams() {
|
||||
return extraConditionParams.get();
|
||||
}
|
||||
|
||||
|
||||
static Object[] getExtraConditionParams(List<String> keys) {
|
||||
if (keys == null || keys.isEmpty()) {
|
||||
return FlexConsts.EMPTY_ARRAY;
|
||||
}
|
||||
Map<String, Object> paramMap = extraConditionParams.get();
|
||||
if (paramMap == null || paramMap.isEmpty()) {
|
||||
return new Object[keys.size()];
|
||||
}
|
||||
|
||||
Object[] params = new Object[keys.size()];
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
params[i] = paramMap.get(keys.get(i));
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
public static <Entity> void queryRelations(BaseMapper<?> mapper, List<Entity> entities) {
|
||||
doQueryRelations(mapper, entities, 0, depthThreadLocal.get());
|
||||
@ -109,8 +155,6 @@ public class RelationManager {
|
||||
try {
|
||||
relations.forEach(relation -> {
|
||||
|
||||
Class mappingType = relation.getMappingType();
|
||||
|
||||
Set<Object> targetValues;
|
||||
List<Row> mappingRows = null;
|
||||
|
||||
@ -159,7 +203,7 @@ public class RelationManager {
|
||||
}
|
||||
|
||||
QueryWrapper queryWrapper = relation.buildQueryWrapper(targetValues);
|
||||
List<?> targetObjectList = mapper.selectListByQueryAs(queryWrapper, mappingType);
|
||||
List<?> targetObjectList = mapper.selectListByQueryAs(queryWrapper, relation.getMappingType());
|
||||
if (CollectionUtil.isNotEmpty(targetObjectList)) {
|
||||
doQueryRelations(mapper, targetObjectList, currentDepth + 1, maxDepth);
|
||||
relation.join(entities, targetObjectList, mappingRows);
|
||||
|
||||
@ -31,11 +31,11 @@ class ToManyRelation<SelfEntity> extends AbstractRelation<SelfEntity> {
|
||||
public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField,
|
||||
String joinTable, String joinSelfColumn, String joinTargetColumn,
|
||||
String dataSource, Class<SelfEntity> selfEntityClass, Field relationField,
|
||||
List<Condition> extraConditions) {
|
||||
String extraCondition) {
|
||||
super(selfField, targetSchema, targetTable, targetField,
|
||||
joinTable, joinSelfColumn, joinTargetColumn,
|
||||
dataSource, selfEntityClass, relationField,
|
||||
extraConditions
|
||||
extraCondition
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -50,9 +50,7 @@ public class Account implements Serializable {
|
||||
joinTable = "tb_role_mapping",
|
||||
joinSelfColumn = "account_id",
|
||||
joinTargetColumn = "role_id",
|
||||
extraConditions = {
|
||||
@Condition(column = "name", logic = "is not null"),
|
||||
}
|
||||
extraCondition = "(name like '%2%' or id > 1)"
|
||||
)
|
||||
private List<Role> roles;
|
||||
|
||||
|
||||
@ -1,15 +1,9 @@
|
||||
package com.mybatisflex.test.relation.onetoone;
|
||||
|
||||
import com.mybatisflex.core.mybatis.FlexConfiguration;
|
||||
import com.mybatisflex.core.table.TableInfo;
|
||||
import com.mybatisflex.core.table.TableInfoFactory;
|
||||
|
||||
public class MainTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TableInfo tableInfo = TableInfoFactory.ofEntityClass(Book.class);
|
||||
tableInfo.buildResultMap(new FlexConfiguration());
|
||||
|
||||
System.out.println(tableInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user