假设我有以下 HQL:
String hql = "select e.aField from MyEntity as e";
如果我想重构并将MyEntity
's 的成员变量的名称更改为其他名称aField
,我还必须更改 Strings 中整个代码中的所有匹配项。如果我忘记更改一个 hql 字符串,代码就会中断。
我怎样才能避免这种情况发生?
假设我有以下 HQL:
String hql = "select e.aField from MyEntity as e";
如果我想重构并将MyEntity
's 的成员变量的名称更改为其他名称aField
,我还必须更改 Strings 中整个代码中的所有匹配项。如果我忘记更改一个 hql 字符串,代码就会中断。
我怎样才能避免这种情况发生?
您可以使用NamedQueries - 您将 HQL 作为任何实体上的注释值,并在启动时将它们编译为 SQL。如果您在 hql 中有任何错误,您将无法启动您的 WebApp。
使用一个足够聪明的 IDE,知道如何为你做这件事,比如 IntelliJ。如果我重命名一个类或变量,IntelliJ 会找到所有用途并为我管理更改。
我相信您正在寻找我一直在寻找的东西......并找到了!
我使用自定义 Hibernate 模板来生成我的 Java 代码。我只是拿了一份他们的副本,然后开始胡闹。这听起来比实际更可怕——相信我。
我将以下代码添加到PojoFields.ftl文件中:
// These static property values are being generated by the POJO templates (PojoFields.ftl) <#foreach field in pojo.getAllPropertiesIterator()> <#if pojo.getMetaAttribAsBool(field, "gen-property", true)> <#assign name = pojo.getPropertyName(field) type = pojo.getJavaTypeName(field, jdk5)> public static final String ${field.name}_propname = "${field.name}"; <#foreach column in field.getColumnIterator()> <#if pojo.getJavaTypeName(field, jdk5) == "String"> public static final int ${field.name}_len = ${column.getLength()?c}; <#break> </#if> </#foreach> </#if> </#foreach>
对于所有属性,它会生成一个具有属性名称的公共最终静态字符串。
对于 String 属性,它会生成一个具有字段长度的 public final static int。
public static final String postalCode_propname = "postalCode";
public static final int postalCode_len = 15;
只要我始终使用这些静态变量并且从不对它们的值进行硬编码,我就可以避免与数据库结构更改相关的运行时错误。
例子:
Criteria criteria = session.createCriteria(ClPost.class).add(
Restrictions.ne(ClPost.postalCode_propname, "90210"));
String hql = "select e." + ClPost.postalCode_propname
+ " from " + ClPost.class.getSimpleName() + " as e";
你不能,因为它们只是字符串(根据定义很难重构)
选项: 1. 使用 Criteria 而不是 HQL 2. 使用 NHibernateToLinq 3. 为每个类创建所有属性的枚举并在 HQL 中使用它(需要连接)