如何避免HQL中的硬编码字段名Hibernate?

时间:2009-06-09 09:16:31

标签: hibernate refactoring hql hard-coding

假设我有以下HQL:

String hql = "select e.aField from MyEntity as e";

如果我想重构并将MyEntity的成员变量aField的名称更改为其他名称,我还必须更改字符串中整个代码中的所有实例。如果我忘记更改一个hql字符串代码中断。

如何避免这种情况发生?

5 个答案:

答案 0 :(得分:4)

您可以使用NamedQueries - 将您的HQL作为注释的值放在任何实体上,并在启动时将它们编译为SQL。如果你在hql中有任何错误,你将无法启动你的WebApp。

答案 1 :(得分:2)

使用足够智能的IDE,知道如何为您完成,例如IntelliJ。如果我重命名一个类或变量,IntelliJ会查找每个用户并为我管理更改。

答案 2 :(得分:1)

我相信你正在寻找我正在寻找的东西......并找到了!

我使用自定义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。

对于String属性,它会生成一个具有字段长度的公共final static static。

public static final String  postalCode_propname         = "postalCode";
public static final int     postalCode_len              = 15;

只要我总是使用这些静态变量并且永远不会对其值进行硬编码,我将避免出现与数据库结构更改相关的RunTime错误。

示例:

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";

答案 3 :(得分:0)

你不能,因为它们只是字符串(根据定义难以重构)

答案 4 :(得分:0)

选项:  1.使用Criteria而不是HQL  2.使用NHibernateToLinq  3.为每个类创建一个包含所有属性的枚举,并在你的HQL中使用它(需要连接)