由將SQL查詢結果轉化為pojo的想到的

來源:互聯網
上載者:User

今天在網上上看見一篇“將SQL查詢結果轉化為pojo對象的”部落格,博主自訂做了一個類如下:

import java.lang.reflect.Field;  
import java.util.List;  
 
import org.hibernate.HibernateException;  
import org.hibernate.property.ChainedPropertyAccessor;  
import org.hibernate.property.PropertyAccessor;  
import org.hibernate.property.PropertyAccessorFactory;  
import org.hibernate.property.Setter;  
import org.hibernate.transform.ResultTransformer;    /**
 * 完成native sql查詢資料(數組)到pojo對象的轉化
 * @author warison
 *
 * Oct 26, 2009
 */
public class PojoTransformer implements ResultTransformer {  
     private static final long serialVersionUID = 1L;  
     private Class<? extends BaseModel> resultClass;  
     private Setter[] setters;  
     private PropertyAccessor propertyAccessor;  
       
     public  PojoTransformer(Class<? extends BaseModel> resultClass) {  
         if(resultClass==null)
          throw new IllegalArgumentException("resultClass cannot be null");  
         this.resultClass = resultClass;  
         propertyAccessor = new ChainedPropertyAccessor(new PropertyAccessor[] { PropertyAccessorFactory.getPropertyAccessor(resultClass,null), PropertyAccessorFactory.getPropertyAccessor("field")});        
     }  
  
     //結果轉換時,HIBERNATE調用此方法  
     public Object transformTuple(Object[] tuple, String[] aliases) {  
         Object result;  
           
         try {  
             if(setters==null) {//首先初始化,取得目標POJO類的所有SETTER方法  
                 setters = new Setter[aliases.length];  
                 for (int i = 0; i < aliases.length; i++) {  
                     String alias = aliases[i];  
                     if(alias != null) {  
                         //我的邏輯主要是在getSetterByColumnName方法裡面,其它都是HIBERNATE的另一個類中COPY的  
                         //這裡填充所需要的SETTER方法  
                         setters[i] = getSetterByColumnName(alias);  
                     }  
                 }  
             }  
             result = resultClass.newInstance();  
               
             //這裡使用SETTER方法填充POJO對象  
             for (int i = 0; i < aliases.length; i++) {  
                 if(setters[i]!=null) {  
                     setters[i].set(result, tuple[i], null);  
                 }  
             }  
         } catch (InstantiationException e) {  
             throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName());  
         } catch (IllegalAccessException e) {  
             throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName());  
         }  
           
         return result;  
     }  
  
     //根據資料庫欄位名在POJO尋找JAVA屬性名稱,參數就是資料庫欄位名,如:USER_ID  
     private Setter getSetterByColumnName(String alias) {  
         //取得POJO所有屬性名稱  
         Field[] fields = resultClass.getDeclaredFields();  
         if(fields==null || fields.length==0){  
             throw new RuntimeException("實體"+resultClass.getName()+"不含任何屬性");  
         }  
         //把欄位名中所有的下杠去除  
         String proName = alias.replaceAll("_", "").toLowerCase();  
         for (Field field : fields) {  
             if(field.getName().toLowerCase().equals(proName)){//去除下杠的欄位名如果和屬性名稱對得上,就取這個SETTER方法  
                 return propertyAccessor.getSetter(resultClass, field.getName());  
             }  
         }  
         throw new RuntimeException("找不到資料庫欄位 :"+ alias + " 對應的POJO屬性或其getter方法,比如資料庫欄位為USER_ID或USERID,那麼JAVA屬性應為userId");  
     }  
  
     @SuppressWarnings("unchecked")  
     public List transformList(List collection) {  
         return collection;  
     }  

}

 

 

public class PojoUser extends BaseModel {
 private String pwd;
 private String userName;
 private String userId;
 
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 public String getUserId() {
  return userId;
 }
 public void setUserId(String userId) {
  this.userId = userId;
 }
 public String getPwd() {
  return pwd;
 }
 public void setPwd(String pwd) {
  this.pwd = pwd;
 }
}

測試方法:

String queryString="select user_id userId,user_name userName from oa_user";

SQLQuery  query = sessionFactory.openSession().createSQLQuery(queryString);

query.setResultTransformer(new PojoTransformer(pojoClass));  

query.list(); 

看到這裡,容易想到,hiernate3.2以後好像已經支援這種方法

SQLQuery  query = sessionFactory.openSession().createSQLQuery(queryString);
  query.addScalar("userName", Hibernate.STRING);
  query.setResultTransformer(Transformers.aliasToBean(pojoClass));

System.out.println(((PojoUser)list.get(0)).getUserName());

結果發現如果query.addScalar("userName", Hibernate.STRING);定義為

query.addScalar("userId", Hibernate.STRING);

列印的結果就是null(實際上是存在值的),不盡感動hiernate的愚蠢,難道沒有設定全部屬性(或當前查詢對應屬性的方法嗎),如果像hiernate的做,豈不是要將所有查詢的屬性都設定一次query.addScalar。

看到這裡可能你會用query.addEntity(PojoUser.class);反駁我,可以使用query.addEntity(PojoUser.class);前提是PojoUser.class已經做了映射。

相比下,上面博主的方法還算是可行。

類似問題,很容易讓我想到ibtatis的處理方式,弄過ibatis的人都曉得,累世的問題簡直就是小菜。

到這裡不盡想說一句“不要迷戀Hibernate,Hibernate只是一傳說。。。” 。畢竟hiernate的最終目標是hql查詢支援,對於sql的支援可能還是存在一定的缺陷。o(∩_∩)o...哈哈

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.