1. 程式人生 > >解決Hibernate原生SQL對映問題

解決Hibernate原生SQL對映問題



在問答裡和論壇中,經常看到有人問,怎樣將使用本地SQL查詢出來的結果對映為值物件的問題,這裡就Hibernate中提供的方法做個結論。前提,這裡沒有使用屬性的延遲載入技術。

  假設有個值對像,如下:

  Java程式碼   

package test; 
 
public class Person { 
  private Long id; 
  private String name; 
  private Long age; 
  private Long phone; 
  private String address; 
 
  public Person(Long id, String name, Long age, Long phone, String address) { 
    this.id = id; 
    this.name = name; 
    this.age = age; 
    this.phone = phone; 
    this.address = address; 
  } 
 
  public Long getId() { 
    return id; 
  } 
 
  public void setId(Long id) { 
    this.id = id; 
  } 
 
  public String getName() { 
    return name; 
  } 
 
  public void setName(String name) { 
    this.name = name; 
  } 
 
  public Long getAge() { 
    return age; 
  } 
 
  public void setAge(Long age) { 
    this.age = age; 
  } 
 
  public Long getPhone() { 
    return phone; 
  } 
 
  public void setPhone(Long phone) { 
    this.phone = phone; 
  } 
 
  public String getAddress() { 
    return address; 
  } 
 
  public void setAddress(String address) { 
    this.address = address; 
  } 
}

  如果查詢全部五列記錄的話,那麼只要

  Java程式碼  

List list = getHibernateTemplate().loadAll(Person.class);

    如果只需要查詢id,name,age三列記錄呢?那麼就要新增構造方法了,

  Java程式碼   

 public Person(Long id, String name, Long age) { 
 this.id = id; 
 this.name = name; 
 this.age = age; 
 }

    然後呢,就可以通過HQL來進行查詢。

  Java程式碼  

List list = getHibernateTemplate().find("select new test.Person(id,name,age) from Person");

    這個方法通常可以滿足需要了,只是如果,只需要查詢id,name,phone三列記錄的話,還新增構造方法?不行了,會出現構造方法衝突了。有個辦法:

  Java程式碼  

List list = getSession().createQuery("select id,name,phone from person") 
   .addScalar("id",Hibernate.Long).addScalar("name").addScalar("phone",Hibernate.Long) 
   .addEntity(Person.class);

  但是,這個只適用於存在Person實體的,如果Hibernate中沒有進行Person對映的呢,系統中只存在一個JavaBean。

  Java程式碼  

List list = getSession().createSQLQuery("select id \"id\",name \"name\",phone \"phone\" from person") 
   .addScalar("id",Hibernate.Long).addScalar("name").addScalar("phone",Hibernate.Long) 
   .setResultTransformer(Transformers.aliasToBean(Person.class)));

  那麼Hibernate就會自動將查出來的三列內容組裝到VO物件中去,只是程式碼量有點大,而且名稱都需要重新定義為小寫的,在Oracle中查出來的列都預設為大寫的(不知道其它資料庫怎麼樣)

  這個辦法就不依賴於構造方法了,只需要定義私有變數,設定getter/setter方法就行了。

  不過如果更猛點的,根本就沒有JavaBean物件可以填充怎麼辦,Hibernate可以將查出來的列組裝到集合類中去。如Map。

  Java程式碼  

List list = getSession().createSQLQuery("select * from person") 
          .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

  除了這個Transformers還可以將列轉化為List。

  Java程式碼  

List list = getSession().createSQLQuery("select * from person") 
          .setResultTransformer(Transformers.T0_LIST);

  到此,還可以通過繼承Transformers將結果對映為其它物件,不累述了,基本功能夠用了。

----------------------------------------------------------------------------------------------------------

String hql ="SELECT apply.productid \"id\",count(apply.productid) \"count\"FROM Applyservice apply GROUP BY productid";
         Query query  = this.getSession().createSQLQuery(hql)
                                          .addScalar("id", Hibernate.STRING)
                                          .addScalar("count", Hibernate.INTEGER)
                                          .setResultTransformer(Transformers.aliasToBean(SqlObject.class));

轉:http://tech.ddvip.com/2009-09/1253541828133808.html