2009-06-09 67 views
2

假設我有以下HQL:如何避免HQL,Hibernate中的硬編碼字段名稱?

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

如果我想重構和改變MyEntity的成員變量aField的名稱別的東西,我也必須改變所有出現在整個代碼字符串。如果我忘記更改一個hql字符串,代碼就會中斷。

我該如何避免發生這種情況?

回答

0

你不能因爲他們是唯一的字符串(很難通過定義來重構)

2

使用IDE這是足夠聰明,知道如何做到這一點的你,喜歡的IntelliJ。如果我重命名一個類或變量,IntelliJ會查找所有用途併爲我管理變更。

4

您可以使用NamedQueries - 您將HQL作爲註釋的值放在任何實體上,並且它們在啓動時編譯爲SQL。如果你在hql中有任何錯誤,你將無法啓動你的WebApp。

0

選項: 1.使用標準,而不是HQL的 2.使用NHibernateToLinq 3.爲每個類創建所有屬性的枚舉和使用,在您HQL(需要連接)

+1

有了標準,你還需要有字段名稱爲字符串。 Restrictions.eq(「fieldname」,foo) - 這與重構有相同的問題。 – davidsheldon 2009-06-09 22:19:33

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> 

所有屬性,它會生成具有屬性名稱的公共最後靜態字符串。

對於字符串屬性,它生成具有字段長度的公共最終靜態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";