避免对Hibernate属性进行硬编码



如果数据库或Hibernate配置发生更改,我不会在源代码中包含使用硬编码的Hibernate属性名称,以避免潜在的错误。

我总是使用Hibernate Criteria和我创建的以下Hibernate Utils.getPropertyName()方法来实现这一点。

/**
* Get a Hibernate property name.<p>
*
* <b>NOTE:</b> This method assumes all property names start with a lower-case character.
*
* @param methodChecker
*        - An ignored value. This parameter is a place-holder for a call to the "get" method for the property of interest.
* @param methodName
*        - The name of the "get" method used to retrieve the property of interest
* @return The property name
*/
public static String getPropertyName(Object methodChecker, String methodName)
{
String propertyName;
if (methodName.startsWith("get"))
{
propertyName = methodName.substring(3, 4).toLowerCase(Locale.ENGLISH)
+ methodName.substring(4);
}
else if (methodName.startsWith("is"))
{
propertyName = methodName.substring(2, 3).toLowerCase(Locale.ENGLISH)
+ methodName.substring(3);
}
else
{
throw new IllegalArgumentException("method name did not start with 'is' or 'get'");
}
return propertyName;
}

为了使用它,我调用该属性的"get"方法作为第一个参数,并硬编码第二个属性的"get"方法的名称。

使用这种方法,Hibernate配置或数据库更改将导致COMPILE-TIME ERRORS,而不是RUN-TIME ERRORS

例如,如果供应商属性被重命名为vendorname,则以下代码将导致运行时间错误

Product Product=(Product)session.createCriteria(Product.class).add(Property.forName("vendor").eq(vendor)).uniqueResult()

要修复代码,所有出现的vendor都必须替换为供应商名称。显然,这很容易出错,而且可能非常耗时。

我使用以下语句实现了相同的功能:

Product Product=(Product)session.createCriteria(Product.class).add(Property.forName(Hibernate Utils.getPropertyName(myProduct.getVendor(),"getVendor")).eq(vendor)).uniqueResult()

如果vendor属性被重命名为供应商名称,则第二种方法将导致编译时间错误,因为getVendor()方法将更改为getVendorname()。

我想知道是否还有另一种方法——它可以让我完全消除Hibernate Utils.getPropertyName()。

谢谢!

我认为这不是一个好的设计。你说你没有对房产名称进行硬编码,但你确实这样做了。

首先,您不再只在实体中对特性名称进行一次硬编码,而是对其进行多次硬编码,这增加了拼写错误的机会,或者在设计更改时需要修复其他位置。

如果表或列发生更改,我不会担心您的配置是否经得起将来的考验。您应该有单元和集成测试(您确实有测试,对吗?)来实际测试数据是否正确读取并加载到您的模式中(在测试数据库中)。数据库模式的任何更改都是一个巨大的更改,它肯定会保证对您的代码进行新的更新,因此它不太可能意外或未经通知而发生。最后,如果您只是适当地使用hibernate属性映射,那么您只需要在列名更改时更新一个位置。

最后,如果您想更改对象中的方法名称,那么所有优秀的IDE都将支持重构,以自动更新该方法使用的所有位置。如果您只是传递字符串名称并使用类似JavaBean的名称来确定这是什么方法,那么这将更难做到

最新更新