This commit is contained in:
parent
af03293df7
commit
bf7167e818
|
@ -6,9 +6,11 @@ import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.query.QueryUtils;
|
import org.springframework.data.jpa.repository.query.QueryUtils;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import com.guwan.backend.MergeStrategy.LambdaUtils.PropertyFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义连表查询构建器
|
* 自定义连表查询构建器
|
||||||
|
@ -41,16 +43,16 @@ public class JoinBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加连接表(使用方法引用)
|
* 添加连接表(使用增强的方法引用)
|
||||||
* @param joinClass 要连接的表实体类
|
* @param joinClass 要连接的表实体类
|
||||||
* @param sourceFieldGetter 主表外键字段的getter方法引用
|
* @param sourceFieldGetter 主表外键字段的getter方法引用
|
||||||
* @param targetFieldGetter 连接表目标字段的getter方法引用
|
* @param targetFieldGetter 连接表目标字段的getter方法引用
|
||||||
*/
|
*/
|
||||||
public <J, V> JoinBuilder<T> join(Class<J> joinClass,
|
public <J, V> JoinBuilder<T> join(Class<J> joinClass,
|
||||||
Function<T, V> sourceFieldGetter,
|
PropertyFunction<T, V> sourceFieldGetter,
|
||||||
Function<J, V> targetFieldGetter) {
|
PropertyFunction<J, V> targetFieldGetter) {
|
||||||
String sourceField = getFieldNameFromGetter(sourceFieldGetter);
|
String sourceField = LambdaUtils.getPropertyName(sourceFieldGetter);
|
||||||
String targetField = getFieldNameFromGetter(targetFieldGetter);
|
String targetField = LambdaUtils.getPropertyName(targetFieldGetter);
|
||||||
return join(joinClass, sourceField, targetField);
|
return join(joinClass, sourceField, targetField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,13 +71,13 @@ public class JoinBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加等值条件(使用方法引用)
|
* 添加等值条件(使用增强的方法引用)
|
||||||
* @param entityClass 实体类
|
* @param entityClass 实体类
|
||||||
* @param fieldGetter 字段的getter方法引用
|
* @param fieldGetter 字段的getter方法引用
|
||||||
* @param value 字段值
|
* @param value 字段值
|
||||||
*/
|
*/
|
||||||
public <E, V> JoinBuilder<T> equal(Class<E> entityClass, Function<E, V> fieldGetter, V value) {
|
public <E, V> JoinBuilder<T> equal(Class<E> entityClass, PropertyFunction<E, V> fieldGetter, V value) {
|
||||||
String fieldName = getFieldNameFromGetter(fieldGetter);
|
String fieldName = LambdaUtils.getPropertyName(fieldGetter);
|
||||||
return equal(entityClass, fieldName, value);
|
return equal(entityClass, fieldName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,17 +91,17 @@ public class JoinBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择返回的字段(使用方法引用)
|
* 选择返回的字段(使用增强的方法引用)
|
||||||
* @param fieldGetters 方法引用列表
|
* @param fieldGetters 方法引用列表
|
||||||
*/
|
*/
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public final <E> JoinBuilder<T> select(Class<E> entityClass, Function<E, ?>... fieldGetters) {
|
public final <E> JoinBuilder<T> select(Class<E> entityClass, PropertyFunction<E, ?>... fieldGetters) {
|
||||||
if (selectedFields == null) {
|
if (selectedFields == null) {
|
||||||
selectedFields = new HashMap<>();
|
selectedFields = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] fieldNames = Arrays.stream(fieldGetters)
|
String[] fieldNames = Arrays.stream(fieldGetters)
|
||||||
.map(this::getFieldNameFromGetter)
|
.map(LambdaUtils::getPropertyName)
|
||||||
.toArray(String[]::new);
|
.toArray(String[]::new);
|
||||||
|
|
||||||
selectedFields.put(entityClass, fieldNames);
|
selectedFields.put(entityClass, fieldNames);
|
||||||
|
@ -107,13 +109,13 @@ public class JoinBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加一个具有别名的字段选择(优先级高于select方法)
|
* 添加一个具有别名的字段选择(使用增强的方法引用)
|
||||||
* @param alias 字段别名
|
* @param alias 字段别名
|
||||||
* @param entityClass 实体类
|
* @param entityClass 实体类
|
||||||
* @param fieldGetter 字段的getter方法引用
|
* @param fieldGetter 字段的getter方法引用
|
||||||
*/
|
*/
|
||||||
public <E, V> JoinBuilder<T> selectAs(String alias, Class<E> entityClass, Function<E, V> fieldGetter) {
|
public <E, V> JoinBuilder<T> selectAs(String alias, Class<E> entityClass, PropertyFunction<E, V> fieldGetter) {
|
||||||
String fieldName = getFieldNameFromGetter(fieldGetter);
|
String fieldName = LambdaUtils.getPropertyName(fieldGetter);
|
||||||
|
|
||||||
// 存储字段信息,稍后在configureSelections处理
|
// 存储字段信息,稍后在configureSelections处理
|
||||||
if (selectedFields == null) {
|
if (selectedFields == null) {
|
||||||
|
@ -154,8 +156,8 @@ public class JoinBuilder<T> {
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public final <R> JoinBuilder<T> selectDto(Class<R> dtoClass, FieldMapping<R, ?>... mappings) {
|
public final <R> JoinBuilder<T> selectDto(Class<R> dtoClass, FieldMapping<R, ?>... mappings) {
|
||||||
for (FieldMapping<R, ?> mapping : mappings) {
|
for (FieldMapping<R, ?> mapping : mappings) {
|
||||||
String dtoFieldName = getFieldNameFromGetter(mapping.getDtoFieldGetter());
|
String dtoFieldName = mapping.getDtoFieldName();
|
||||||
String entityFieldName = getFieldNameFromGetter(mapping.getEntityFieldGetter());
|
String entityFieldName = mapping.getEntityFieldName();
|
||||||
Class<?> entityClass = mapping.getEntityClass();
|
Class<?> entityClass = mapping.getEntityClass();
|
||||||
|
|
||||||
// 存储字段信息,稍后在configureSelections处理
|
// 存储字段信息,稍后在configureSelections处理
|
||||||
|
@ -384,117 +386,50 @@ public class JoinBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从getter方法引用中提取属性名
|
* 字段映射定义,用于DTO映射
|
||||||
*/
|
*/
|
||||||
private <E, R> String getFieldNameFromGetter(Function<E, R> getter) {
|
public static class FieldMapping<D, E> {
|
||||||
// 直接尝试从方法引用的toString中获取
|
private final String dtoFieldName;
|
||||||
|
private final String entityFieldName;
|
||||||
|
private final Class<E> entityClass;
|
||||||
|
|
||||||
|
private FieldMapping(String dtoFieldName, String entityFieldName, Class<E> entityClass) {
|
||||||
|
this.dtoFieldName = dtoFieldName;
|
||||||
|
this.entityFieldName = entityFieldName;
|
||||||
|
this.entityClass = entityClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <D, E, V> FieldMapping<D, E> of(PropertyFunction<D, V> dtoFieldGetter, PropertyFunction<E, V> entityFieldGetter) {
|
||||||
|
String dtoFieldName = LambdaUtils.getPropertyName(dtoFieldGetter);
|
||||||
|
String entityFieldName = LambdaUtils.getPropertyName(entityFieldGetter);
|
||||||
|
|
||||||
|
// 通过反射获取entityClass
|
||||||
|
Class<E> entityClass = null;
|
||||||
try {
|
try {
|
||||||
String methodRef = getter.toString();
|
// 尝试从方法引用中提取类信息
|
||||||
if (methodRef.contains("::")) {
|
Method writeReplace = entityFieldGetter.getClass().getDeclaredMethod("writeReplace");
|
||||||
// 处理方法引用格式: com.example.Entity::getName
|
writeReplace.setAccessible(true);
|
||||||
String methodName = methodRef.substring(methodRef.lastIndexOf("::") + 2);
|
Object serializedLambda = writeReplace.invoke(entityFieldGetter);
|
||||||
return extractFieldNameFromMethod(methodName);
|
String implClass = (String) serializedLambda.getClass().getMethod("getImplClass").invoke(serializedLambda);
|
||||||
} else if (methodRef.contains("->")) {
|
implClass = implClass.replace('/', '.');
|
||||||
// 处理Lambda表达式格式: (Entity e) -> e.getName()
|
entityClass = (Class<E>) Class.forName(implClass);
|
||||||
String methodCall = methodRef.substring(methodRef.indexOf("->") + 2).trim();
|
} catch (Exception e) {
|
||||||
String methodName = methodCall.substring(methodCall.lastIndexOf(".") + 1);
|
// 忽略异常,entityClass将在运行时确定
|
||||||
if (methodName.endsWith(")")) {
|
|
||||||
methodName = methodName.substring(0, methodName.indexOf("("));
|
|
||||||
}
|
|
||||||
return extractFieldNameFromMethod(methodName);
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
// 忽略异常,尝试下一种方法
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return new FieldMapping<>(dtoFieldName, entityFieldName, entityClass);
|
||||||
String getterName = getter.getClass().getName();
|
|
||||||
if (getterName.contains("$$Lambda$")) {
|
|
||||||
// 处理Lambda表达式
|
|
||||||
if (getterName.contains("get")) {
|
|
||||||
// 尝试从名称中提取字段名
|
|
||||||
int getIndex = getterName.lastIndexOf("get");
|
|
||||||
if (getIndex >= 0 && getIndex + 3 < getterName.length()) {
|
|
||||||
String fieldName = getterName.substring(getIndex + 3);
|
|
||||||
if (fieldName.indexOf('$') > 0) {
|
|
||||||
fieldName = fieldName.substring(0, fieldName.indexOf('$'));
|
|
||||||
}
|
|
||||||
return fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
// 忽略异常,fallback到基于字符串的方法
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback到基于字符串的方法
|
public String getDtoFieldName() {
|
||||||
String methodReference = getter.toString();
|
return dtoFieldName;
|
||||||
return getFieldNameFromGetterString(methodReference);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getEntityFieldName() {
|
||||||
* 从getter方法字符串中提取属性名
|
return entityFieldName;
|
||||||
*/
|
|
||||||
private String getFieldNameFromGetterString(String methodReference) {
|
|
||||||
// 方法引用的格式通常是:类名::get字段名 或 Lambda表达式
|
|
||||||
if (methodReference.contains("::")) {
|
|
||||||
// 处理方法引用格式: com.example.Entity::getName
|
|
||||||
String methodName = methodReference.substring(methodReference.lastIndexOf("::") + 2);
|
|
||||||
return extractFieldNameFromMethod(methodName);
|
|
||||||
} else if (methodReference.contains("->")) {
|
|
||||||
// 处理Lambda表达式格式: (Entity e) -> e.getName()
|
|
||||||
String methodCall = methodReference.substring(methodReference.indexOf("->") + 2).trim();
|
|
||||||
String methodName = methodCall.substring(methodCall.lastIndexOf(".") + 1);
|
|
||||||
if (methodName.endsWith(")")) {
|
|
||||||
methodName = methodName.substring(0, methodName.indexOf("("));
|
|
||||||
}
|
|
||||||
return extractFieldNameFromMethod(methodName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 无法识别的格式,返回原始字符串
|
public Class<?> getEntityClass() {
|
||||||
return methodReference;
|
return entityClass;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从方法名中提取字段名
|
|
||||||
*/
|
|
||||||
private String extractFieldNameFromMethod(String methodName) {
|
|
||||||
if (methodName.startsWith("get") && methodName.length() > 3) {
|
|
||||||
// getName -> name (首字母小写)
|
|
||||||
String fieldName = methodName.substring(3);
|
|
||||||
return fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
|
|
||||||
} else if (methodName.startsWith("is") && methodName.length() > 2) {
|
|
||||||
// isActive -> active (首字母小写)
|
|
||||||
String fieldName = methodName.substring(2);
|
|
||||||
return fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
|
|
||||||
}
|
|
||||||
return methodName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 首字母大写
|
|
||||||
*/
|
|
||||||
private String capitalize(String str) {
|
|
||||||
if (str == null || str.isEmpty()) {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum Operator {
|
|
||||||
EQUAL
|
|
||||||
// 可以添加更多操作符支持,如LIKE, IN, GREATER_THAN等
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Condition {
|
|
||||||
private final String fieldName;
|
|
||||||
private final Object value;
|
|
||||||
private final Operator operator;
|
|
||||||
|
|
||||||
Condition(String fieldName, Object value, Operator operator) {
|
|
||||||
this.fieldName = fieldName;
|
|
||||||
this.value = value;
|
|
||||||
this.operator = operator;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,47 +459,20 @@ public class JoinBuilder<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private enum Operator {
|
||||||
* 字段映射定义,用于DTO映射
|
EQUAL
|
||||||
*/
|
// 可以添加更多操作符支持,如LIKE, IN, GREATER_THAN等
|
||||||
public static class FieldMapping<D, E> {
|
|
||||||
private final Function<D, ?> dtoFieldGetter;
|
|
||||||
private final Function<E, ?> entityFieldGetter;
|
|
||||||
private final Class<E> entityClass;
|
|
||||||
|
|
||||||
private FieldMapping(Function<D, ?> dtoFieldGetter, Function<E, ?> entityFieldGetter, Class<E> entityClass) {
|
|
||||||
this.dtoFieldGetter = dtoFieldGetter;
|
|
||||||
this.entityFieldGetter = entityFieldGetter;
|
|
||||||
this.entityClass = entityClass;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <D, E, V> FieldMapping<D, E> of(Function<D, V> dtoFieldGetter, Function<E, V> entityFieldGetter) {
|
private static class Condition {
|
||||||
// 通过反射或其他方式获取entityClass
|
private final String fieldName;
|
||||||
Class<E> entityClass = null;
|
private final Object value;
|
||||||
try {
|
private final Operator operator;
|
||||||
// 尝试从方法引用中提取类信息
|
|
||||||
String methodRef = entityFieldGetter.toString();
|
|
||||||
if (methodRef.contains("::")) {
|
|
||||||
String className = methodRef.substring(0, methodRef.indexOf("::"));
|
|
||||||
entityClass = (Class<E>) Class.forName(className);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 忽略异常,entityClass将在运行时确定
|
|
||||||
}
|
|
||||||
|
|
||||||
return new FieldMapping<>(dtoFieldGetter, entityFieldGetter, entityClass);
|
Condition(String fieldName, Object value, Operator operator) {
|
||||||
}
|
this.fieldName = fieldName;
|
||||||
|
this.value = value;
|
||||||
public Function<D, ?> getDtoFieldGetter() {
|
this.operator = operator;
|
||||||
return dtoFieldGetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Function<E, ?> getEntityFieldGetter() {
|
|
||||||
return entityFieldGetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<?> getEntityClass() {
|
|
||||||
return entityClass;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
package com.guwan.backend.MergeStrategy;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.invoke.SerializedLambda;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lambda表达式和方法引用解析工具类
|
||||||
|
*/
|
||||||
|
public class LambdaUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从Lambda表达式或方法引用中提取属性名
|
||||||
|
* @param getter Lambda方法引用
|
||||||
|
* @return 属性名
|
||||||
|
*/
|
||||||
|
public static <T, R> String getPropertyName(PropertyFunction<T, R> getter) {
|
||||||
|
try {
|
||||||
|
// 1. 获取SerializedLambda
|
||||||
|
Method writeReplace = getter.getClass().getDeclaredMethod("writeReplace");
|
||||||
|
writeReplace.setAccessible(true);
|
||||||
|
SerializedLambda serializedLambda = (SerializedLambda) writeReplace.invoke(getter);
|
||||||
|
|
||||||
|
// 2. 从SerializedLambda获取实现方法名
|
||||||
|
String implMethodName = serializedLambda.getImplMethodName();
|
||||||
|
|
||||||
|
// 3. 转换方法名为属性名
|
||||||
|
if (implMethodName.startsWith("get") && implMethodName.length() > 3) {
|
||||||
|
String propertyName = implMethodName.substring(3);
|
||||||
|
return propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1);
|
||||||
|
} else if (implMethodName.startsWith("is") && implMethodName.length() > 2) {
|
||||||
|
String propertyName = implMethodName.substring(2);
|
||||||
|
return propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implMethodName;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 降级到常规正则表达式解析
|
||||||
|
return parsePropertyNameByRegex(getter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用正则表达式解析属性名(备选方案)
|
||||||
|
*/
|
||||||
|
private static <T, R> String parsePropertyNameByRegex(Function<T, R> getter) {
|
||||||
|
// 尝试从Lambda toString()解析
|
||||||
|
String methodRef = getter.toString();
|
||||||
|
|
||||||
|
// 处理方法引用格式: com.example.Entity::getName
|
||||||
|
if (methodRef.contains("::")) {
|
||||||
|
Pattern pattern = Pattern.compile("::get(\\w+)|::is(\\w+)");
|
||||||
|
Matcher matcher = pattern.matcher(methodRef);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String fieldName = matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
|
||||||
|
return fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接从方法名截取
|
||||||
|
String methodName = methodRef.substring(methodRef.lastIndexOf("::") + 2);
|
||||||
|
return extractFieldNameFromMethod(methodName);
|
||||||
|
}
|
||||||
|
// 处理Lambda表达式格式: (Entity e) -> e.getName() 或 e -> e.getName()
|
||||||
|
else if (methodRef.contains("->")) {
|
||||||
|
Pattern pattern = Pattern.compile("->\\s*\\w+\\.get(\\w+)\\(\\)|->\\s*\\w+\\.is(\\w+)\\(\\)");
|
||||||
|
Matcher matcher = pattern.matcher(methodRef);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String fieldName = matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
|
||||||
|
return fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理其他情况 - 也许是已经是字段名
|
||||||
|
return methodRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从方法名中提取字段名
|
||||||
|
*/
|
||||||
|
private static String extractFieldNameFromMethod(String methodName) {
|
||||||
|
if (methodName.startsWith("get") && methodName.length() > 3) {
|
||||||
|
// getName -> name (首字母小写)
|
||||||
|
String fieldName = methodName.substring(3);
|
||||||
|
return fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
|
||||||
|
} else if (methodName.startsWith("is") && methodName.length() > 2) {
|
||||||
|
// isActive -> active (首字母小写)
|
||||||
|
String fieldName = methodName.substring(2);
|
||||||
|
return fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
|
||||||
|
}
|
||||||
|
return methodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可序列化的函数接口 - 用于支持方法引用解析
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface PropertyFunction<T, R> extends Function<T, R>, Serializable {
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package com.guwan.backend.jpaTest;
|
||||||
|
|
||||||
import com.guwan.backend.MergeStrategy.JoinBuilder;
|
import com.guwan.backend.MergeStrategy.JoinBuilder;
|
||||||
import com.guwan.backend.MergeStrategy.JoinBuilder.FieldMapping;
|
import com.guwan.backend.MergeStrategy.JoinBuilder.FieldMapping;
|
||||||
|
import com.guwan.backend.MergeStrategy.LambdaUtils.PropertyFunction;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -40,7 +41,6 @@ public class EmployeeService {
|
||||||
}
|
}
|
||||||
builder.equal(Project.class, "deleted", projectDeleted);
|
builder.equal(Project.class, "deleted", projectDeleted);
|
||||||
|
|
||||||
|
|
||||||
// 使用selectAs设置字段别名,避免使用FieldMapping
|
// 使用selectAs设置字段别名,避免使用FieldMapping
|
||||||
builder.selectAs("employeeId", Employee.class, "id");
|
builder.selectAs("employeeId", Employee.class, "id");
|
||||||
builder.selectAs("employeeName", Employee.class, "name");
|
builder.selectAs("employeeName", Employee.class, "name");
|
||||||
|
@ -53,7 +53,7 @@ public class EmployeeService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用自定义条件查询员工信息
|
* 使用自定义条件查询员工信息
|
||||||
* 使用selectAs来指定字段别名对应DTO构造函数参数
|
* 使用新的方法引用方式
|
||||||
*
|
*
|
||||||
* @param employeeName 员工名称过滤条件,可选
|
* @param employeeName 员工名称过滤条件,可选
|
||||||
* @param departmentName 部门名称过滤条件,可选
|
* @param departmentName 部门名称过滤条件,可选
|
||||||
|
@ -62,11 +62,47 @@ public class EmployeeService {
|
||||||
public List<EmployeeDTO> findEmployees(String employeeName, String departmentName) {
|
public List<EmployeeDTO> findEmployees(String employeeName, String departmentName) {
|
||||||
JoinBuilder<Employee> builder = JoinBuilder.from(Employee.class);
|
JoinBuilder<Employee> builder = JoinBuilder.from(Employee.class);
|
||||||
|
|
||||||
// 添加关联,使用字符串
|
// 尝试使用增强的方法引用
|
||||||
|
try {
|
||||||
|
// 添加关联,使用增强的方法引用
|
||||||
|
builder.join(Department.class,
|
||||||
|
(PropertyFunction<Employee, Long>) Employee::getDepartmentId,
|
||||||
|
(PropertyFunction<Department, Long>) Department::getId);
|
||||||
|
builder.join(Project.class,
|
||||||
|
(PropertyFunction<Employee, Long>) Employee::getProjectId,
|
||||||
|
(PropertyFunction<Project, Long>) Project::getId);
|
||||||
|
|
||||||
|
// 添加查询条件,使用增强的方法引用
|
||||||
|
if (employeeName != null && !employeeName.isEmpty()) {
|
||||||
|
builder.equal(Employee.class,
|
||||||
|
(PropertyFunction<Employee, String>) Employee::getName,
|
||||||
|
employeeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (departmentName != null && !departmentName.isEmpty()) {
|
||||||
|
builder.equal(Department.class,
|
||||||
|
(PropertyFunction<Department, String>) Department::getName,
|
||||||
|
departmentName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用selectAs配合增强的方法引用
|
||||||
|
builder.selectAs("employeeId", Employee.class,
|
||||||
|
(PropertyFunction<Employee, Long>) Employee::getId);
|
||||||
|
builder.selectAs("employeeName", Employee.class,
|
||||||
|
(PropertyFunction<Employee, String>) Employee::getName);
|
||||||
|
builder.selectAs("departmentName", Department.class,
|
||||||
|
(PropertyFunction<Department, String>) Department::getName);
|
||||||
|
builder.selectAs("projectName", Project.class,
|
||||||
|
(PropertyFunction<Project, String>) Project::getName);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
/* // 如果增强方法引用失败,回退到字符串方式
|
||||||
|
builder = JoinBuilder.from(Employee.class);
|
||||||
|
|
||||||
|
// 使用字符串作为回退方案
|
||||||
builder.join(Department.class, "departmentId", "id");
|
builder.join(Department.class, "departmentId", "id");
|
||||||
builder.join(Project.class, "projectId", "id");
|
builder.join(Project.class, "projectId", "id");
|
||||||
|
|
||||||
// 添加查询条件,使用字符串
|
|
||||||
if (employeeName != null && !employeeName.isEmpty()) {
|
if (employeeName != null && !employeeName.isEmpty()) {
|
||||||
builder.equal(Employee.class, "name", employeeName);
|
builder.equal(Employee.class, "name", employeeName);
|
||||||
}
|
}
|
||||||
|
@ -75,11 +111,11 @@ public class EmployeeService {
|
||||||
builder.equal(Department.class, "name", departmentName);
|
builder.equal(Department.class, "name", departmentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 方式2:使用selectAs直接指定字段别名
|
|
||||||
builder.selectAs("employeeId", Employee.class, "id");
|
builder.selectAs("employeeId", Employee.class, "id");
|
||||||
builder.selectAs("employeeName", Employee.class, "name");
|
builder.selectAs("employeeName", Employee.class, "name");
|
||||||
builder.selectAs("departmentName", Department.class, "name");
|
builder.selectAs("departmentName", Department.class, "name");
|
||||||
builder.selectAs("projectName", Project.class, "name");
|
builder.selectAs("projectName", Project.class, "name");*/
|
||||||
|
}
|
||||||
|
|
||||||
// 直接执行查询并映射到DTO
|
// 直接执行查询并映射到DTO
|
||||||
return builder.executeAndMap(entityManager, EmployeeDTO.class);
|
return builder.executeAndMap(entityManager, EmployeeDTO.class);
|
||||||
|
|
Loading…
Reference in New Issue