至于本机查询,没有涉及简单的解决方案。我不得不研究AliasToBeanResultTransformer
该类的实现并在那里进行修复。我通过创建类的副本解决了这个问题,AliasToBeanResultTransformer
并通过以下方式修改了该类的私有initialize
方法:
public class CaseInsensitiveAliasToBeanResultTransformer {
private void initialize(String[] aliases) {
this.aliases = new String[ aliases.length ];
setters = new Setter[aliases.length];
for ( int i = 0; i < aliases.length; i++ ) {
String alias = aliases[i];
if (alias != null) {
this.aliases[i] = alias;
setters[i] = CaseInsensitiveSetter.getSetter(resultClass, alias);
}
}
isInitialized = true;
}
}
这段代码的不同主要在于这一行CaseInsensitiveSetter.getSetter(resultClass, alias)
,我在这里介绍了一个CaseInsensitiveSetter
我将在下面描述的类。此类实现 Setter 接口并允许使用不区分大小写的匹配检索类的 setter 方法 - 因此这将允许我将小写查询别名绑定到我的结果类的正确成员。这是自定义设置器的代码(为简洁起见,仅显示重要的行):
public class CaseInsensitiveSetter {
public static Setter getSetter(Class<?> theClass, String propertyName) {
Setter setter;
if (theClass == Object.class || theClass == null) {
setter = null;
} else {
setter = doGetSetter(theClass, propertyName);
if (setter != null) {
if (!ReflectHelper.isPublic(theClass, setter.getMethod())) {
setter.getMethod().setAccessible(true);
}
} else {
setter = doGetSetter(theClass.getSuperclass(), propertyName);
if (setter == null) {
Class<?>[] interfaces = theClass.getInterfaces();
for (int i = 0; setter == null && i < interfaces.length; i++) {
setter = doGetSetter( interfaces[i], propertyName);
}
}
}
if (setter == null) {
throw new PropertyNotFoundException(
"Could not find a setter for property " +
propertyName + " in class " + theClass.getName());
}
}
return setter;
}
// The actual work is done here
private static Setter doGetSetter(Class<?> resultClass, String propertyName) {
Method[] methods = resultClass.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
// only carry on if the method has 1 parameter
if ( methods[i].getParameterTypes().length == 1 ) {
String methodName = methods[i].getName();
if (methodName.startsWith("set")) {
String testStdMethod = methodName.substring(3);
if (testStdMethod.equalsIgnoreCase(propertyName)) {
Setter result = new CustomSetter(
resultClass, methods[i], propertyName);
return result;
}
}
}
}
return null;
}
}
其来源是基于BaseSetter
Hibernate 自带的类,但改为支持不区分大小写的匹配。尽管如此,这个类,以及 Hibernate 使用的原始类,由于大量使用反射而缺乏性能。
另外,请记住,如果结果类包含名称在不区分大小写的比较中相同的不同属性,则当前代码只会选择其中一个,并且可能无法按预期工作。