在MongoTemplate的时候常常使用类名、类的属性名进行操作,而使用字符串容易出现修改类属性后很难检查的问题,所以推荐使用统一的工具类进行相关名称的获取
类相关工具类
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
/**
* 类相关工具类
*/
public class ClassUtil {
/**
* 获取类私有字段名称
*/
public static String[] getPrivateFields(Class<?> cla) {
Field[] fields = cla.getDeclaredFields();
List<String> list = new ArrayList<>();
for (Field field : fields) {
if (field.getModifiers() == Modifier.PRIVATE) {
list.add(field.getName());
}
}
return list.toArray(new String[0]);
}
/**
* 根据类名获取表名
*/
public static String getTableName(Class<?> cla) {
String simpleName = cla.getSimpleName();
StringBuilder result = new StringBuilder();
boolean nextLowerCase = false;
boolean firstCharacter = true;
for (int i = 0; i < simpleName.length(); i++) {
char ch = simpleName.charAt(i);
if (ch == '_') {
nextLowerCase = true;
} else {
if (nextLowerCase || firstCharacter) {
result.append(Character.toLowerCase(ch));
nextLowerCase = false;
firstCharacter = false;
} else {
result.append(ch);
}
}
}
return result.toString();
}
}
获取字段名称
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.function.Function;
/**
* Java8通过Function函数获取字段名称(获取实体类的字段名称)
*/
public class FieldUtil {
/**
* 使Function获取序列化能力
*/
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
}
/**
* 获取实体类的字段名称
*/
public static <T> String get(SFunction<T, ?> fn) {
SerializedLambda serializedLambda = getSerializedLambda(fn);
// 从lambda信息取出method、field、class等
String fieldName = serializedLambda.getImplMethodName().substring("get".length());
fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
// 对ID进行处理
if (Objects.equals("id", fieldName)) {
fieldName = "_id";
}
return fieldName;
}
private static <T> SerializedLambda getSerializedLambda(SFunction<T, ?> fn) {
// 从function取出序列化方法
Method writeReplaceMethod;
try {
writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
// 从序列化方法取出序列化的lambda信息
boolean isAccessible = writeReplaceMethod.isAccessible();
writeReplaceMethod.setAccessible(true);
SerializedLambda serializedLambda;
try {
serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
writeReplaceMethod.setAccessible(isAccessible);
return serializedLambda;
}
}